diff --git a/documentation/development-docs/azure-powershell-developer-guide.md b/documentation/development-docs/azure-powershell-developer-guide.md index c77499190037..a610c477244e 100644 --- a/documentation/development-docs/azure-powershell-developer-guide.md +++ b/documentation/development-docs/azure-powershell-developer-guide.md @@ -248,17 +248,58 @@ _Note_: As mentioned in the prerequisites section, set the PowerShell [execution ## Using Azure TestFramework -Please see our guide on [Using Azure TestFramework](../testing-docs/using-azure-test-framework.md) for information on how to setup the appropriate connection string and record tests using the `Microsoft.Rest.ClientRuntime.Azure.TestFramework` package. +Please see our guide on [Using Azure TestFramework](../testing-docs/using-azure-test-framework.md) for information on how to setup the appropriate connection string and record tests. ## Scenario Tests +### Adding Test Project + +- Create a new folder called `ScenarioTests` +- Create a new folder called `SessionRecords` +- Inside the `ScenarioTests` folder, create a new class called `TestRunner` +- In the `TestRunner` class, it should have the similar field and constructor like shown below. The parameter values passed in are based on the real situation. +```csharp + protected readonly ITestRunner TestRunner; + + protected TestRunner(ITestOutputHelper output) + { + TestRunner = TestManager.CreateInstance(output) + .WithProjectSubfolderForTests("ScenarioTests") + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithCommonPsScripts(new[] + { + @"Common.ps1", + @"../AzureRM.Resources.ps1", + @"../AzureRM.Storage.ps1" + }) + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + ... + }) + .WithNewRecordMatcherArguments( + userAgentsToIgnore: new Dictionary + { + ... + }, + resourceProviders: new Dictionary + { + ... + } + ) + .Build(); + } +``` + ### Adding Scenario Tests - Create a new class in `.Test` + - The new class must inherit from the `TestRunner` class in this project. - Add `[Fact]` as an attribute to every test - Add `[Trait(Category.AcceptanceType, Category.CheckIn)]` as an attribute to any test that should be run during CI in Playback mode. - Add `[Trait(Category.AcceptanceType, Category.LiveOnly)]` as an attribute to any test that cannot be run in Playback mode (for example, if a test depends on a Dataplane SDK). -- Create a ps1 file in the same folder that contains the actual tests ([see sample](../../src/Media/Media.Test/ScenarioTests)) +- Create a ps1 file in the same folder that contains the actual tests. +- The name of the ps1 file should exactly match with name of the class. ([see sample](../../src/Media/Media.Test/ScenarioTests)) - Use `Assert-AreEqual x y` to verify that values are the same - Use `Assert-AreNotEqual x y` to verify that values are not the same - Use `Assert-Throws scriptblock message` to verify an exception is being thrown @@ -302,10 +343,7 @@ Create this environment variables for the AD scenario tests: ### Recording/Running Tests - Set up environment variables using New-TestCredential as described [here](../testing-docs/using-azure-test-framework.md#new-testcredential) -- Run the test in Visual Studio in the Test Explorer window and make sure you got a generated JSON file that matches the test name in the bin folder under the `SessionRecords` folder -- Copy this `SessionRecords` folder and place it inside the test project - - Inside Visual Studio, add all of the generated JSON files, making sure to change the "Copy to Output Directory" property for each one to "Copy if newer" - - Make sure that all of these JSON files appear in your `.Test.csproj` file +- Run the test in Visual Studio in the Test Explorer window and make sure you got a generated JSON file that matches the test name under the `SessionRecords` folder # After Development diff --git a/documentation/testing-docs/using-azure-test-framework.md b/documentation/testing-docs/using-azure-test-framework.md index 62a47854810a..4033f22612d7 100644 --- a/documentation/testing-docs/using-azure-test-framework.md +++ b/documentation/testing-docs/using-azure-test-framework.md @@ -28,11 +28,9 @@ - Import the `Repo-Tasks` module that helps to perform basic repository tasks - Run the command `Import-Module .\Repo-Tasks.psd1` -## Acquiring TestFramework +## Azure PowerShell TestFramework -The `TestFramework` library is available on NuGet at https://www.nuget.org/packages/Microsoft.Rest.ClientRuntime.Azure.TestFramework/ . - -Instructions on manually downloading the library are available on NuGet, however, `TestFramework` will automatically be downloaded as part of the build process, so the manual download is usually not necessary. +Azure PowerShell repo now has its own test framework located under `tools\TestFx`, which supports recording all the HTTP requests from behind Azure PowerShell cmdlets and then playing them back. The target framework of test is .Net Core 3.1, please ensure .Net runtime Microsoft.NETCore.App 3.1 is installed. You can list all installed version via `dotnet --info`. @@ -129,8 +127,7 @@ AZURE_TEST_MODE=Record ## Record or Playback Tests -- [Run the tests](https://github.com/Azure/azure-powershell/blob/main/documentation/development-docs/azure-powershell-developer-guide.md#recordingrunning-tests) and make sure that you got a generated `.json` file that matches the test name in the bin folder under the `SessionRecords` folder -- Copy the `SessionRecords` folder inside the test project and add all `*.json` files in Visual Studio setting "Copy to Output Directory" property to "Copy if newer" +- [Run the tests](https://github.com/Azure/azure-powershell/blob/main/documentation/development-docs/azure-powershell-developer-guide.md#recordingrunning-tests) and make sure that you got a generated `.json` file that matches the test name under the `SessionRecords` folder in the test project. - To assure that the records work fine, delete the connection string (default mode is Playback mode) OR change HttpRecorderMode within the connection string to "Playback" and run the tests ## Change Test Environment settings at run-time diff --git a/src/Accounts/Accounts.Test/AutosaveTests.cs b/src/Accounts/Accounts.Test/AutosaveTests.cs index 198a76b65f0b..310c937b7d02 100644 --- a/src/Accounts/Accounts.Test/AutosaveTests.cs +++ b/src/Accounts/Accounts.Test/AutosaveTests.cs @@ -25,6 +25,7 @@ using Microsoft.Azure.Commands.Profile.Context; using Microsoft.Azure.Commands.ScenarioTest; using Microsoft.Azure.Commands.ResourceManager.Common; +using Microsoft.Azure.Commands.TestFx.Mocks; namespace Microsoft.Azure.Commands.Profile.Test { diff --git a/src/Accounts/Accounts.Test/AzureRMProfileTests.cs b/src/Accounts/Accounts.Test/AzureRMProfileTests.cs index 568135327616..b72777bd0d62 100644 --- a/src/Accounts/Accounts.Test/AzureRMProfileTests.cs +++ b/src/Accounts/Accounts.Test/AzureRMProfileTests.cs @@ -21,6 +21,7 @@ using Microsoft.Azure.Commands.Profile.Models; using Microsoft.Azure.Commands.Profile.Test; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.Management.ResourceManager.Version2021_01_01.Models; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.Rest; @@ -61,11 +62,11 @@ private static RMProfileClient SetupTestEnvironment(List tenants, params Guid.NewGuid().ToString(), DefaultTenant.ToString()); var subscriptionList = new Queue>(subscriptionLists); var clientFactory = new MockSubscriptionClientFactory(tenants, subscriptionList); - var mock = new MockClientFactory(new List + var mock = new MockClientFactory(null, new List { clientFactory.GetSubscriptionClientVerLatest(), clientFactory.GetSubscriptionClientVer2016() - }, true); + }); mock.MoqClients = true; AzureSession.Instance.ClientFactory = mock; var sub = new AzureSubscription() @@ -89,11 +90,11 @@ private static AzureRmProfile SetupLogin(List tenants, params List>(subscriptionLists); var clientFactory = new MockSubscriptionClientFactory(tenants, subscriptionList); - var mock = new MockClientFactory(new List + var mock = new MockClientFactory(null, new List { clientFactory.GetSubscriptionClientVerLatest(), clientFactory.GetSubscriptionClientVer2016() - }, true); + }); mock.MoqClients = true; AzureSession.Instance.ClientFactory = mock; var sub = new AzureSubscription() diff --git a/src/Accounts/Accounts.Test/AzureRMProfileTestsForMultitenant.cs b/src/Accounts/Accounts.Test/AzureRMProfileTestsForMultitenant.cs index fb9c70f76ec6..e0845fd617cd 100644 --- a/src/Accounts/Accounts.Test/AzureRMProfileTestsForMultitenant.cs +++ b/src/Accounts/Accounts.Test/AzureRMProfileTestsForMultitenant.cs @@ -18,6 +18,7 @@ using Microsoft.Azure.Commands.Profile.Models; using Microsoft.Azure.Commands.Profile.Test.Mocks; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using Microsoft.WindowsAzure.Commands.ScenarioTest; diff --git a/src/Accounts/Accounts.Test/ContextCmdletTests.cs b/src/Accounts/Accounts.Test/ContextCmdletTests.cs index ae1ba4f8eb5c..06cf2f290eb1 100644 --- a/src/Accounts/Accounts.Test/ContextCmdletTests.cs +++ b/src/Accounts/Accounts.Test/ContextCmdletTests.cs @@ -14,8 +14,6 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Models; -using Microsoft.Azure.Commands.Profile; -using Microsoft.Azure.Commands.Profile.Models; // TODO: Remove IfDef #if NETSTANDARD using Microsoft.Azure.Commands.Profile.Models.Core; @@ -29,12 +27,13 @@ using Xunit.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using System; -using Microsoft.Azure.Commands.ScenarioTest.Extensions; using Microsoft.Azure.Commands.Profile.Context; using System.Linq; using Microsoft.Azure.Commands.Common.Authentication.ResourceManager; using Microsoft.Azure.Commands.Profile.Common; using Microsoft.Azure.Commands.ScenarioTest.Mocks; +using Microsoft.Azure.Commands.TestFx.Mocks; +using Microsoft.Azure.Commands.TestFx; namespace Microsoft.Azure.Commands.Profile.Test { diff --git a/src/Accounts/Accounts.Test/Mocks/AccountMockClientFactory.cs b/src/Accounts/Accounts.Test/Mocks/AccountMockClientFactory.cs index e67ef2861b2c..4cf8eebd0067 100644 --- a/src/Accounts/Accounts.Test/Mocks/AccountMockClientFactory.cs +++ b/src/Accounts/Accounts.Test/Mocks/AccountMockClientFactory.cs @@ -13,6 +13,7 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Rest; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using System.Collections.Generic; @@ -24,7 +25,7 @@ class AccountMockClientFactory : MockClientFactory, IClientFactory public delegate object NextClient(); private NextClient nextClient; - public AccountMockClientFactory(NextClient next, bool throwIfClientNotSpecified = true):base(new List(), throwIfClientNotSpecified) + public AccountMockClientFactory(NextClient next, bool throwIfClientNotSpecified = true) : base(null, null) { nextClient = next; } diff --git a/src/Accounts/Accounts.Test/ProfileCmdletTests.cs b/src/Accounts/Accounts.Test/ProfileCmdletTests.cs index 6837ac90dfc0..06f7425ef783 100644 --- a/src/Accounts/Accounts.Test/ProfileCmdletTests.cs +++ b/src/Accounts/Accounts.Test/ProfileCmdletTests.cs @@ -16,6 +16,7 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using Microsoft.WindowsAzure.Commands.ScenarioTest; diff --git a/src/Accounts/Accounts.Test/SubscriptionClientSwitchTest.cs b/src/Accounts/Accounts.Test/SubscriptionClientSwitchTest.cs index b6a339d36fc3..1efff5f850ac 100644 --- a/src/Accounts/Accounts.Test/SubscriptionClientSwitchTest.cs +++ b/src/Accounts/Accounts.Test/SubscriptionClientSwitchTest.cs @@ -18,6 +18,7 @@ using Microsoft.Azure.Commands.Profile.Models; using Microsoft.Azure.Commands.Profile.Test.Mocks; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.Management.ResourceManager.Version2021_01_01.Models; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.Rest.Azure; diff --git a/src/Accounts/Accounts.Test/TenantCmdletMockTests.cs b/src/Accounts/Accounts.Test/TenantCmdletMockTests.cs index c85a3f147b08..61d97af097e3 100644 --- a/src/Accounts/Accounts.Test/TenantCmdletMockTests.cs +++ b/src/Accounts/Accounts.Test/TenantCmdletMockTests.cs @@ -18,6 +18,7 @@ using Microsoft.Azure.Commands.Profile; using Microsoft.Azure.Commands.Profile.Models; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using Microsoft.WindowsAzure.Commands.ScenarioTest; diff --git a/src/Accounts/Authentication.Test/AuthenticationFactoryTests.cs b/src/Accounts/Authentication.Test/AuthenticationFactoryTests.cs index f8b989d8a307..5b69c3ff1d25 100644 --- a/src/Accounts/Authentication.Test/AuthenticationFactoryTests.cs +++ b/src/Accounts/Authentication.Test/AuthenticationFactoryTests.cs @@ -37,6 +37,7 @@ using Moq; using System.ServiceModel.Channels; using Azure.Core; +using Microsoft.Azure.Commands.TestFx.Mocks; namespace Common.Authentication.Test { diff --git a/src/Accounts/Authentication.Test/AuthenticatorsTest/ServicePrincipalAuthenticatorTests.cs b/src/Accounts/Authentication.Test/AuthenticatorsTest/ServicePrincipalAuthenticatorTests.cs index ef39b6bf0cd2..56a4574165f4 100644 --- a/src/Accounts/Authentication.Test/AuthenticatorsTest/ServicePrincipalAuthenticatorTests.cs +++ b/src/Accounts/Authentication.Test/AuthenticatorsTest/ServicePrincipalAuthenticatorTests.cs @@ -18,19 +18,17 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.PowerShell.Authenticators; using Microsoft.Azure.PowerShell.Authenticators.Factories; -using Microsoft.Azure.Test.HttpRecorder; using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using Microsoft.WindowsAzure.Commands.ScenarioTest; +using Microsoft.WindowsAzure.Commands.Utilities.Common; using Moq; -using Xunit; -using Xunit.Abstractions; using System; using System.Security; using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; - - +using Xunit; +using Xunit.Abstractions; namespace Common.Authenticators.Test { diff --git a/src/Accounts/Authentication.Test/ClientFactoryTests.cs b/src/Accounts/Authentication.Test/ClientFactoryTests.cs index 448355d9864d..5fee13eee919 100644 --- a/src/Accounts/Authentication.Test/ClientFactoryTests.cs +++ b/src/Accounts/Authentication.Test/ClientFactoryTests.cs @@ -21,6 +21,7 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; using System.Net.Http.Headers; +using Microsoft.Azure.Commands.TestFx.Mocks; namespace Common.Authentication.Test { diff --git a/src/Accounts/Authentication.Test/PSSerializationTests.cs b/src/Accounts/Authentication.Test/PSSerializationTests.cs index 71a3ef2b47cf..9b50a24de842 100644 --- a/src/Accounts/Authentication.Test/PSSerializationTests.cs +++ b/src/Accounts/Authentication.Test/PSSerializationTests.cs @@ -11,19 +11,19 @@ // See the License for the specific language governing permissions and // limitations under the License. // ---------------------------------------------------------------------------------- +using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.Profile.Models; using Microsoft.Azure.Commands.Profile.Models.Core; -using Microsoft.Azure.Commands.ScenarioTest.Extensions; +using Microsoft.Azure.Commands.TestFx; using Microsoft.WindowsAzure.Commands.ScenarioTest; using System; using System.Globalization; +using System.Linq; using System.Management.Automation; using Xunit; -using System.Linq; -using Microsoft.Azure.Commands.Common.Authentication; namespace Common.Authentication.Test { diff --git a/src/Accounts/Authentication.Test/SessionInitializationTests.cs b/src/Accounts/Authentication.Test/SessionInitializationTests.cs index 3f3d0c785b11..5afd11717111 100644 --- a/src/Accounts/Authentication.Test/SessionInitializationTests.cs +++ b/src/Accounts/Authentication.Test/SessionInitializationTests.cs @@ -26,6 +26,7 @@ using Moq; using System.IO; using System.Text; +using Microsoft.Azure.Commands.TestFx.Mocks; namespace Common.Authentication.Test { diff --git a/src/Aks/Aks.Test/ScenarioTests/AksTestRunner.cs b/src/Aks/Aks.Test/ScenarioTests/AksTestRunner.cs index 9c72262e0c5d..9c8560f1723c 100644 --- a/src/Aks/Aks.Test/ScenarioTests/AksTestRunner.cs +++ b/src/Aks/Aks.Test/ScenarioTests/AksTestRunner.cs @@ -60,7 +60,7 @@ protected AksTestRunner(ITestOutputHelper output) {"Microsoft.Features", null}, {"Microsoft.Authorization", null} } - ).WithMockContextAction(() => + ).WithMockContextAction(mockContext => { if (HttpMockServer.GetCurrentMode() == HttpRecorderMode.Playback) { diff --git a/src/AnalysisServices/AnalysisServices.Test/ScenarioTests/UrlDecodingRecordMatcher.cs b/src/AnalysisServices/AnalysisServices.Test/ScenarioTests/UrlDecodingRecordMatcher.cs index 344db3923050..c8f94608b7e4 100644 --- a/src/AnalysisServices/AnalysisServices.Test/ScenarioTests/UrlDecodingRecordMatcher.cs +++ b/src/AnalysisServices/AnalysisServices.Test/ScenarioTests/UrlDecodingRecordMatcher.cs @@ -18,6 +18,7 @@ using System.Linq; using System.Net.Http; using System.Text; +using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.WindowsAzure.Commands.ScenarioTest; namespace Microsoft.Azure.Commands.DataLake.Test.ScenarioTests diff --git a/src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/TestsFixture.cs b/src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/ApiManagementHelper.cs similarity index 83% rename from src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/TestsFixture.cs rename to src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/ApiManagementHelper.cs index abbd326ea820..4ba5161caddb 100644 --- a/src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/TestsFixture.cs +++ b/src/ApiManagement/ApiManagement.ServiceManagement.Test/ScenarioTests/ApiManagementHelper.cs @@ -10,41 +10,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ApiManagement; using Microsoft.Azure.Management.ApiManagement.Models; -using Microsoft.Azure.Test; -using System; -using System.Diagnostics; -using System.Linq; -using System.Net; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; -using TestEnvironmentFactory = Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestEnvironmentFactory; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using System; +using System.Linq; using ApiManagementClient = Microsoft.Azure.Management.ApiManagement.ApiManagementClient; namespace Microsoft.Azure.Commands.ApiManagement.ServiceManagement.Test.ScenarioTests { - public class TestsFixture : RMTestBase - { - public TestsFixture() - { - // Initialize has bug which causes null reference exception - HttpMockServer.FileSystemUtilsObject = new FileSystemUtils(); - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - using (var context = MockContext.Start(callingClassType, mockName)) - { - var resourceManagementClient = ApiManagementHelper.GetResourceManagementClient(context); - resourceManagementClient.TryRegisterSubscriptionForResource(); - } - } - } - public static class ApiManagementHelper { public static ApiManagementClient GetApiManagementClient(MockContext context) diff --git a/src/Attestation/Attestation.Test/ScenarioTests/AttestationTestRunner.cs b/src/Attestation/Attestation.Test/ScenarioTests/AttestationTestRunner.cs index 7cb8bba2c3b5..56f93d342143 100644 --- a/src/Attestation/Attestation.Test/ScenarioTests/AttestationTestRunner.cs +++ b/src/Attestation/Attestation.Test/ScenarioTests/AttestationTestRunner.cs @@ -86,7 +86,7 @@ private static AttestationClient GetAttestationClient(MockContext context) var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); string servicePrincipal = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalKey); string servicePrincipalSecret = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalSecretKey); - string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.AADTenantKey); + string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.TenantIdKey); // Create credentials var clientCredentials = new ClientCredential(servicePrincipal, servicePrincipalSecret); diff --git a/src/Az.Shared.props b/src/Az.Shared.props index cdf0664826a4..9c15521bd77c 100644 --- a/src/Az.Shared.props +++ b/src/Az.Shared.props @@ -8,9 +8,15 @@ - false + false + false + false + false + false + false + false true - \ No newline at end of file + diff --git a/src/Az.Test.props b/src/Az.Test.props index aa54a8d8f76d..8cbf3178a198 100644 --- a/src/Az.Test.props +++ b/src/Az.Test.props @@ -9,6 +9,13 @@ .Test + + + <_Parameter1>TestProjectPath + <_Parameter2>$(MSBuildProjectDirectory) + + + netcoreapp3.1 @@ -27,13 +34,11 @@ - - diff --git a/src/Batch/Batch.Test/ScenarioTests/BatchApplicationPackageTests.cs b/src/Batch/Batch.Test/ScenarioTests/BatchApplicationPackageTests.cs index df8eaaf6c781..96ee8214d715 100644 --- a/src/Batch/Batch.Test/ScenarioTests/BatchApplicationPackageTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/BatchApplicationPackageTests.cs @@ -12,24 +12,20 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; +using Microsoft.WindowsAzure.Commands.ScenarioTest; using Microsoft.WindowsAzure.Commands.Utilities.Common; using Xunit; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class BatchApplicationPackageTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class BatchApplicationPackageTests : BatchTestRunner { private readonly string filePath = "Resources\\TestApplicationPackage.zip".AsAbsoluteLocation(); private const string version = "foo"; - public XunitTracingInterceptor _logger; - public BatchApplicationPackageTests(Xunit.Abstractions.ITestOutputHelper output) + public BatchApplicationPackageTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] @@ -38,29 +34,21 @@ public void TestUploadApplicationPackage() { string id = "newApplicationPackage"; - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => - { - return new string[] - { - string.Format(string.Format("Test-UploadApplicationPackage '{0}' '{1}' '{2}'", id, version, filePath)) - }; - }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateApplicationPackage(controller, context, id, version, filePath); + ScenarioTestHelpers.CreateApplicationPackage(this, context, id, version, filePath); }, () => { - ScenarioTestHelpers.DeleteApplicationPackage(controller, context, id, version); - ScenarioTestHelpers.DeleteApplication(controller, context, id); + ScenarioTestHelpers.DeleteApplicationPackage(this, context, id, version); + ScenarioTestHelpers.DeleteApplication(this, context, id); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-UploadApplicationPackage '{id}' '{version}' '{filePath}'" + ); } [Fact] @@ -69,29 +57,21 @@ public void TestUpdateApplicationPackage() { string id = "updateApplicationPackage"; - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => - { - return new string[] - { - string.Format(string.Format("Test-UpdateApplicationPackage '{0}' '{1}' '{2}'", id, version, filePath)) - }; - }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateApplicationPackage(controller, context, id, version, filePath); + ScenarioTestHelpers.CreateApplicationPackage(this, context, id, version, filePath); }, () => { - ScenarioTestHelpers.DeleteApplicationPackage(controller, context, id, version); - ScenarioTestHelpers.DeleteApplication(controller, context, id); + ScenarioTestHelpers.DeleteApplicationPackage(this, context, id, version); + ScenarioTestHelpers.DeleteApplication(this, context, id); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-UpdateApplicationPackage '{id}' '{version}' '{filePath}'" + ); } [Fact] @@ -101,27 +81,15 @@ public void TestCreatePoolWithApplicationPackage() string id = "createPoolWithApplicationPackage"; string poolId = "testCreatePoolWithAppPackages"; - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => - { - return new string[] - { - string.Format(string.Format("Test-CreatePoolWithApplicationPackage '{0}' '{1}' '{2}'", id, version, poolId)) - }; - }, - () => + TestRunner.RunTestScript( + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateApplicationPackage(controller, context, id, version, filePath); + ScenarioTestHelpers.CreateApplicationPackage(this, context, id, version, filePath); }, - () => - { - }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-CreatePoolWithApplicationPackage '{id}' '{version}' '{poolId}'" + ); } [Fact] @@ -131,31 +99,23 @@ public void TestUpdatePoolWithApplicationPackage() string id = "updatePoolWithApplicationPackage"; string poolId = "testUpdatePoolWithAppPackages"; - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => - { - return new string[] - { - string.Format("Test-UpdatePoolWithApplicationPackage '{0}' '{1}' '{2}'", id, version, poolId) - }; - }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateApplicationPackage(controller, context, id, version, filePath); - ScenarioTestHelpers.CreateTestPool(controller, context, poolId, targetDedicated: 1, targetLowPriority: 0); + ScenarioTestHelpers.CreateApplicationPackage(this, context, id, version, filePath); + ScenarioTestHelpers.CreateTestPool(this, context, poolId, targetDedicated: 1, targetLowPriority: 0); }, () => { - ScenarioTestHelpers.DeleteApplicationPackage(controller, context, id, version); - ScenarioTestHelpers.DeleteApplication(controller, context, id); - ScenarioTestHelpers.DeletePool(controller, context, poolId); + ScenarioTestHelpers.DeleteApplicationPackage(this, context, id, version); + ScenarioTestHelpers.DeleteApplication(this, context, id); + ScenarioTestHelpers.DeletePool(this, context, poolId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-UpdatePoolWithApplicationPackage '{id}' '{version}' '{poolId}'" + ); } } } \ No newline at end of file diff --git a/src/Batch/Batch.Test/ScenarioTests/BatchApplicationTests.cs b/src/Batch/Batch.Test/ScenarioTests/BatchApplicationTests.cs index 257eb7d49a02..a49d5a96d3c3 100644 --- a/src/Batch/Batch.Test/ScenarioTests/BatchApplicationTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/BatchApplicationTests.cs @@ -12,30 +12,23 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System; -using Microsoft.Azure.Test; -using Microsoft.WindowsAzure.Commands.Utilities.Common; -using Xunit; using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.Azure.ServiceManagement.Common.Models; +using Xunit; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class BatchApplicationTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class BatchApplicationTests : BatchTestRunner { - public XunitTracingInterceptor _logger; - - public BatchApplicationTests(Xunit.Abstractions.ITestOutputHelper output) + public BatchApplicationTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddApplication() { - BatchController.NewInstance.RunPsTest(_logger, string.Format("Test-AddApplication")); + TestRunner.RunTestScript("Test-AddApplication"); } } } \ No newline at end of file diff --git a/src/Batch/Batch.Test/ScenarioTests/BatchController.cs b/src/Batch/Batch.Test/ScenarioTests/BatchController.cs deleted file mode 100644 index d8746894f7c6..000000000000 --- a/src/Batch/Batch.Test/ScenarioTests/BatchController.cs +++ /dev/null @@ -1,182 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.ScenarioTest; -using Microsoft.Azure.Internal.Common; -using Microsoft.Azure.Management.Batch; -using Microsoft.Azure.Management.Internal.Resources; -using Microsoft.Azure.Management.Network; -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; - -namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests -{ - public class BatchController - { - internal static string BatchAccount; - internal static string BatchAccountKey; - internal static string BatchAccountUrl; - internal static string BatchResourceGroup; - internal static string Subscription; - - private readonly EnvironmentSetupHelper _helper; - - public ResourceManagementClient ResourceManagementClient { get; private set; } - - public BatchManagementClient BatchManagementClient { get; private set; } - - public NetworkManagementClient NetworkManagementClient { get; private set; } - - public AzureRestClient AzureRestClient { get; private set; } - - public static BatchController NewInstance => new BatchController(); - - public BatchController() - { - _helper = new EnvironmentSetupHelper(); - } - - public void RunPsTest(XunitTracingInterceptor logger, params string[] scripts) - { - TestExecutionHelpers.SetUpSessionAndProfile(); - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - RunPsTestWorkflow( - logger, - () => scripts, - // no custom initializer - null, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void RunPsTestWorkflow( - XunitTracingInterceptor logger, - Func scriptBuilder, - Action initialize, - Action cleanup, - string callingClassType, - string mockName) - { - _helper.TracingInterceptor = logger; - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Network", null}, - {"Microsoft.Authorization", null} - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new PermissiveRecordMatcherWithApiExclusion(true, d, providersToIgnore); - - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (var context = MockContext.Start(callingClassType, mockName)) - { - SetupManagementClients(context); - - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - var callingClassName = callingClassType - .Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) - .Last(); - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.GetRMModulePath("Az.Batch.psd1"), - _helper.GetRMModulePath("Az.Network.psd1"), - "AzureRM.Resources.ps1"); - - try - { - initialize?.Invoke(); - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - _helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - } - } - } - - private void SetupManagementClients(MockContext context) - { - ResourceManagementClient = GetResourceManagementClient(context); - BatchManagementClient = GetBatchManagementClient(context); - NetworkManagementClient = GetNetworkManagementClient(context); - AzureRestClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - - _helper.SetupManagementClients(ResourceManagementClient, BatchManagementClient, NetworkManagementClient, AzureRestClient); - } - - private ResourceManagementClient GetResourceManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private NetworkManagementClient GetNetworkManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private BatchManagementClient GetBatchManagementClient(MockContext context) - { - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - BatchAccount = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountName); - BatchAccountKey = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountKey); - BatchAccountUrl = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountEndpoint); - BatchResourceGroup = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountResourceGroup); - - HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountName] = BatchAccount; - HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountEndpoint] = BatchAccountUrl; - HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountResourceGroup] = BatchResourceGroup; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - BatchAccount = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountName]; - BatchAccountKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="; - BatchAccountUrl = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountEndpoint]; - - if (HttpMockServer.Variables.ContainsKey(ScenarioTestHelpers.BatchAccountResourceGroup)) - { - BatchResourceGroup = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountResourceGroup]; - } - } - var result = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - Subscription = result.SubscriptionId; - - return result; - } - } -} diff --git a/src/Batch/Batch.Test/ScenarioTests/BatchTestRunner.cs b/src/Batch/Batch.Test/ScenarioTests/BatchTestRunner.cs index b0fa65b7c0b5..766d9a39b69b 100644 --- a/src/Batch/Batch.Test/ScenarioTests/BatchTestRunner.cs +++ b/src/Batch/Batch.Test/ScenarioTests/BatchTestRunner.cs @@ -25,9 +25,22 @@ namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - // Needs more initialize parameters after setup HttpMockServer. public class BatchTestRunner { + internal static string BatchAccount; + internal static string BatchAccountKey; + internal static string BatchAccountUrl; + internal static string BatchResourceGroup; + internal static string Subscription; + + public ResourceManagementClient ResourceManagementClient { get; private set; } + + public BatchManagementClient BatchManagementClient { get; private set; } + + public NetworkManagementClient NetworkManagementClient { get; private set; } + + public AzureRestClient AzureRestClient { get; private set; } + protected readonly ITestRunner TestRunner; protected BatchTestRunner(ITestOutputHelper output) @@ -59,7 +72,65 @@ protected BatchTestRunner(ITestOutputHelper output) {"Microsoft.Authorization", null} } ) + .WithManagementClients( + GetResourceManagementClient, + GetBatchManagementClient, + GetNetworkManagementClient, + GetAzureRestClient + ) .Build(); } + + private ResourceManagementClient GetResourceManagementClient(MockContext context) + { + var client = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + ResourceManagementClient = client; + return client; + } + + private BatchManagementClient GetBatchManagementClient(MockContext context) + { + if (HttpMockServer.Mode == HttpRecorderMode.Record) + { + BatchAccount = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountName); + BatchAccountKey = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountKey); + BatchAccountUrl = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountEndpoint); + BatchResourceGroup = Environment.GetEnvironmentVariable(ScenarioTestHelpers.BatchAccountResourceGroup); + + HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountName] = BatchAccount; + HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountEndpoint] = BatchAccountUrl; + HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountResourceGroup] = BatchResourceGroup; + } + else if (HttpMockServer.Mode == HttpRecorderMode.Playback) + { + BatchAccount = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountName]; + BatchAccountKey = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000=="; + BatchAccountUrl = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountEndpoint]; + + if (HttpMockServer.Variables.ContainsKey(ScenarioTestHelpers.BatchAccountResourceGroup)) + { + BatchResourceGroup = HttpMockServer.Variables[ScenarioTestHelpers.BatchAccountResourceGroup]; + } + } + + var client = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + Subscription = client.SubscriptionId; + BatchManagementClient = client; + return client; + } + + private NetworkManagementClient GetNetworkManagementClient(MockContext context) + { + var client = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + NetworkManagementClient = client; + return client; + } + + private AzureRestClient GetAzureRestClient(MockContext context) + { + var client = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + AzureRestClient = client; + return client; + } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/CertificateTests.cs b/src/Batch/Batch.Test/ScenarioTests/CertificateTests.cs index 438f7f0f8505..372b1320bd8d 100644 --- a/src/Batch/Batch.Test/ScenarioTests/CertificateTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/CertificateTests.cs @@ -12,64 +12,61 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.Azure.Batch; using Microsoft.Azure.Batch.Common; using Microsoft.WindowsAzure.Commands.ScenarioTest; +using System; +using System.IO; +using System.Security.Cryptography.X509Certificates; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class CertificateTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class CertificateTests : BatchTestRunner { - public XunitTracingInterceptor _logger; - - public CertificateTests(Xunit.Abstractions.ITestOutputHelper output) + public CertificateTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCertificateCrudOperations() { - BatchController.NewInstance.RunPsTest(_logger, "Test-CertificateCrudOperations"); + TestRunner.RunTestScript("Test-CertificateCrudOperations"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCancelCertificateDelete() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; - string thumbprint = null; + X509Certificate2 cert = new X509Certificate2(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources/BatchTestCert01.cer")); + string thumbprint = cert.Thumbprint.ToLowerInvariant(); string poolId = "certPool"; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-TestCancelCertificateDelete '{0}' '{1}'", BatchTestHelpers.TestCertificateAlgorithm, thumbprint) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - thumbprint = ScenarioTestHelpers.AddTestCertificate(controller, context, BatchTestHelpers.TestCertificateFileName).ToLowerInvariant(); + thumbprint = ScenarioTestHelpers.AddTestCertificate(this, context, BatchTestHelpers.TestCertificateFileName).ToLowerInvariant(); CertificateReference certRef = new CertificateReference(); certRef.StoreLocation = CertStoreLocation.CurrentUser; certRef.StoreName = "My"; certRef.ThumbprintAlgorithm = BatchTestHelpers.TestCertificateAlgorithm; certRef.Thumbprint = thumbprint; certRef.Visibility = CertificateVisibility.Task; - ScenarioTestHelpers.CreateTestPool(controller, context, poolId, targetDedicated: 0, targetLowPriority: 0, certReference: certRef); - ScenarioTestHelpers.DeleteTestCertificate(controller, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); - ScenarioTestHelpers.WaitForCertificateToFailDeletion(controller, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); + ScenarioTestHelpers.CreateTestPool(this, context, poolId, targetDedicated: 0, targetLowPriority: 0, certReference: certRef); + ScenarioTestHelpers.DeleteTestCertificate(this, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); + ScenarioTestHelpers.WaitForCertificateToFailDeletion(this, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); }, () => { - ScenarioTestHelpers.DeletePool(controller, context, poolId); - ScenarioTestHelpers.DeleteTestCertificate(controller, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); + ScenarioTestHelpers.DeletePool(this, context, poolId); + ScenarioTestHelpers.DeleteTestCertificate(this, context, BatchTestHelpers.TestCertificateAlgorithm, thumbprint); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-TestCancelCertificateDelete '{BatchTestHelpers.TestCertificateAlgorithm}' '{thumbprint}'" + ); } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.cs b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.cs index c2358c4547ec..48c2715d1e40 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.cs @@ -12,113 +12,80 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class ComputeNodeTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class ComputeNodeTests : BatchTestRunner { private const string poolId = ScenarioTestHelpers.SharedPool; private const string iaasPoolId = ScenarioTestHelpers.SharedIaasPool; - public XunitTracingInterceptor _logger; - public ComputeNodeTests(Xunit.Abstractions.ITestOutputHelper output) + public ComputeNodeTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestRemoveComputeNodes() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string removeNodePoolId = "removenodepool"; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-RemoveComputeNodes '{0}'", removeNodePoolId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestPool(controller, context, removeNodePoolId, targetDedicated: 2, targetLowPriority: 0); - ScenarioTestHelpers.WaitForSteadyPoolAllocation(controller, context, removeNodePoolId); + ScenarioTestHelpers.CreateTestPool(this, context, removeNodePoolId, targetDedicated: 2, targetLowPriority: 0); + ScenarioTestHelpers.WaitForSteadyPoolAllocation(this, context, removeNodePoolId); }, () => { - ScenarioTestHelpers.DeletePool(controller, context, removeNodePoolId); + ScenarioTestHelpers.DeletePool(this, context, removeNodePoolId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-RemoveComputeNodes '{removeNodePoolId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestRebootAndReimageComputeNode() { - BatchController controller = BatchController.NewInstance; - BatchAccountContext context = null; - string computeNodeId = null; - string computeNodeId2 = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-RebootAndReimageComputeNode '{0}' '{1}' '{2}'", poolId, computeNodeId, computeNodeId2) }; }, - () => + TestRunner.RunTestScript( + mockContext => { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId, 0); - computeNodeId2 = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId, 1); - ScenarioTestHelpers.WaitForIdleComputeNode(controller, context, poolId, computeNodeId); - ScenarioTestHelpers.WaitForIdleComputeNode(controller, context, poolId, computeNodeId2); + _ = new ScenarioTestContext(); }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-RebootAndReimageComputeNode '{poolId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDisableAndEnableComputeNodeScheduling() { - BatchController controller = BatchController.NewInstance; - BatchAccountContext context = null; - string computeNodeId = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-DisableAndEnableComputeNodeScheduling '{0}' '{1}'", poolId, computeNodeId) }; }, - () => + TestRunner.RunTestScript( + mockContext => { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId); - ScenarioTestHelpers.WaitForIdleComputeNode(controller, context, poolId, computeNodeId); + _ = new ScenarioTestContext(); }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-DisableAndEnableComputeNodeScheduling '{poolId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetComputeNodeRemoteLoginSettings() { - BatchController controller = BatchController.NewInstance; - BatchAccountContext context = null; - string computeNodeId = null; - - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-GetRemoteLoginSettings '{0}' '{1}'", iaasPoolId, computeNodeId) }; }, - () => + TestRunner.RunTestScript( + mockContext => { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, iaasPoolId); + _ = new ScenarioTestContext(); }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-GetRemoteLoginSettings '{iaasPoolId}'" + ); } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.ps1 b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.ps1 index bb44b32f05ba..bf00405b22dd 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.ps1 +++ b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeTests.ps1 @@ -54,10 +54,17 @@ Tests rebooting and reimaging a compute node #> function Test-RebootAndReimageComputeNode { - param([string]$poolId, [string]$computeNodeId, [string]$computeNodeId2) + param([string]$poolId) $context = New-Object Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext + $computeNodes = Get-AzBatchComputeNode -PoolId $poolId -BatchContext $context + $computeNodeId = $computeNodes[0].Id + $computeNodeId2 = $computeNodes[1].Id + + WaitForIdleComputeNode $context $poolId $computeNodeId + WaitForIdleComputeNode $context $poolId $computeNodeId2 + $rebootOption = ([Microsoft.Azure.Batch.Common.ComputeNodeRebootOption]::Terminate) $reimageOption = ([Microsoft.Azure.Batch.Common.ComputeNodeReimageOption]::Terminate) @@ -78,10 +85,15 @@ Tests disabling and enabling compute node scheduling #> function Test-DisableAndEnableComputeNodeScheduling { - param([string]$poolId, [string]$computeNodeId) + param([string]$poolId) $context = New-Object Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext + $computeNodes = Get-AzBatchComputeNode -PoolId $poolId -BatchContext $context + $computeNodeId = $computeNodes[0].Id + + WaitForIdleComputeNode $context $poolId $computeNodeId + $disableOption = ([Microsoft.Azure.Batch.Common.DisableComputeNodeSchedulingOption]::Terminate) Get-AzBatchComputeNode $poolId $computeNodeId -BatchContext $context | Disable-AzBatchComputeNodeScheduling -DisableSchedulingOption $disableOption -BatchContext $context @@ -100,12 +112,35 @@ Tests getting remote login settings from compute node #> function Test-GetRemoteLoginSettings { - param([string]$poolId, [string]$computeNodeId) + param([string]$poolId) $context = New-Object Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext + + $computeNodes = Get-AzBatchComputeNode -PoolId $poolId -BatchContext $context + $computeNodeId = $computeNodes[0].Id + $remoteLoginSettings = Get-AzBatchComputeNode $poolId $computeNodeId -BatchContext $context | Get-AzBatchRemoteLoginSettings -BatchContext $context Assert-AreNotEqual $null $remoteLoginSettings.IPAddress Assert-AreNotEqual $null $remoteLoginSettings.Port } +function WaitForIdleComputeNode +{ + param([Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext]$context, [string]$poolId, [string]$computeNodeId) + + $start = [DateTime]::Now + $timeout = Compute-TestTimeout 600 + $end = $start.AddSeconds($timeout) + + $computeNode = Get-AzBatchComputeNode -Id $computeNodeId -PoolId $poolId -BatchContext $context -Select "id,state" + while ($computeNode.State -ne 'idle') + { + if ([DateTime]::Now -gt $end) + { + throw [System.TimeoutException] "Timed out waiting for idle compute node" + } + Start-TestSleep 5000 + $computeNode = Get-AzBatchComputeNode -Id $computeNodeId -PoolId $poolId -BatchContext $context -Select "id,state" + } +} \ No newline at end of file diff --git a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.cs b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.cs index fb6baa399f56..77574754b44b 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.cs @@ -12,42 +12,31 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class ComputeNodeUserTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class ComputeNodeUserTests : BatchTestRunner { private const string poolId = ScenarioTestHelpers.SharedPool; - public XunitTracingInterceptor _logger; - public ComputeNodeUserTests(Xunit.Abstractions.ITestOutputHelper output) + public ComputeNodeUserTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestComputeNodeUserEndToEnd() { - BatchController controller = BatchController.NewInstance; - BatchAccountContext context = null; - string computeNodeId = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-ComputeNodeUserEndToEnd '{0}' '{1}'", poolId, computeNodeId) }; }, - () => + TestRunner.RunTestScript( + mockContext => { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId); + _ = new ScenarioTestContext(); }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-ComputeNodeUserEndToEnd '{poolId}'" + ); } } diff --git a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.ps1 b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.ps1 index f52eab4f026e..dc13b7af3988 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.ps1 +++ b/src/Batch/Batch.Test/ScenarioTests/ComputeNodeUserTests.ps1 @@ -18,12 +18,15 @@ Tests compute node user operations #> function Test-ComputeNodeUserEndToEnd { - param([string]$poolId, [string]$computeNodeId) + param([string]$poolId) $context = New-Object Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext $userName = "userendtoend" $password1 = ConvertTo-SecureString "Password1234!" -AsPlainText -Force + $computeNodes = Get-AzBatchComputeNode -PoolId $poolId -BatchContext $context + $computeNodeId = $computeNodes[0].Id + # Create a user New-AzBatchComputeNodeUser -PoolId $poolId -ComputeNodeId $computeNodeId -Name $userName -Password $password1 -BatchContext $context diff --git a/src/Batch/Batch.Test/ScenarioTests/FileTests.cs b/src/Batch/Batch.Test/ScenarioTests/FileTests.cs index 09b1eca2f869..dc8aa3c0f4e7 100644 --- a/src/Batch/Batch.Test/ScenarioTests/FileTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/FileTests.cs @@ -12,25 +12,22 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; +using System.Collections.Generic; +using System.Linq; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class FileTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class FileTests : BatchTestRunner { private const string poolId = ScenarioTestHelpers.SharedPool; private const string startTaskStdOutName = ScenarioTestHelpers.SharedPoolStartTaskStdOut; private const string startTaskStdOutContent = ScenarioTestHelpers.SharedPoolStartTaskStdOutContent; - public XunitTracingInterceptor _logger; - - public FileTests(Xunit.Abstractions.ITestOutputHelper output) + public FileTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact(Skip = "Successful re-recording, but fails in playback. See issue https://github.com/Azure/azure-powershell/issues/7512")] @@ -38,29 +35,27 @@ public FileTests(Xunit.Abstractions.ITestOutputHelper output) [Trait(Category.RunType, Category.DesktopOnly)] public void TestGetNodeFileContentByTask() { - BatchController controller = BatchController.NewInstance; string jobId = "nodeFileContentByTask"; string taskId = "testTask"; string fileName = "testFile.txt"; string nodeFilePath = string.Format("wd\\{0}", fileName); string fileContents = "test file contents"; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-GetNodeFileContentByTask '{0}' '{1}' '{2}' '{3}'", jobId, taskId, nodeFilePath, fileContents) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId, string.Format("cmd /c echo {0} > {1}", fileContents, fileName)); - ScenarioTestHelpers.WaitForTaskCompletion(controller, context, jobId, taskId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId, string.Format("cmd /c echo {0} > {1}", fileContents, fileName)); + ScenarioTestHelpers.WaitForTaskCompletion(this, context, jobId, taskId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-GetNodeFileContentByTask '{jobId}' '{taskId}' '{nodeFilePath}' '{fileContents}'" + ); } [Fact(Skip = "Successful re-recording, but fails in playback. See issue https://github.com/Azure/azure-powershell/issues/7512")] @@ -68,98 +63,83 @@ public void TestGetNodeFileContentByTask() [Trait(Category.RunType, Category.DesktopOnly)] public void TestGetNodeFileContentByComputeNode() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string computeNodeId = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-GetNodeFileContentByComputeNode '{0}' '{1}' '{2}' '{3}'", poolId, computeNodeId, startTaskStdOutName, startTaskStdOutContent) }; }, - () => - { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId); - }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + TestRunner.RunTestScript( + mockContext => + { + context = new ScenarioTestContext(); + computeNodeId = ScenarioTestHelpers.GetComputeNodeId(this, context, poolId); + }, + $"Test-GetNodeFileContentByComputeNode '{poolId}' '{computeNodeId}' '{startTaskStdOutName}' '{startTaskStdOutContent}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetRemoteDesktopProtocolFile() { - BatchController controller = BatchController.NewInstance; - BatchAccountContext context = null; - string computeNodeId = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-GetRDPFile '{0}' '{1}'", poolId, computeNodeId) }; }, - () => - { - context = new ScenarioTestContext(); - computeNodeId = ScenarioTestHelpers.GetComputeNodeId(controller, context, poolId); - }, - null, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + TestRunner.RunTestScript( + mockContext => + { + _ = new ScenarioTestContext(); + }, + $"Test-GetRDPFile '{poolId}'" + ); } [Fact(Skip = "Successful re-recording, but fails in playback. See issue https://github.com/Azure/azure-powershell/issues/7512")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDeleteNodeFileByTask() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string jobId = "deletetaskFile"; string taskId = "task1"; string fileName = "testFile.txt"; string filePath = string.Format("wd\\{0}", fileName); - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-DeleteNodeFileByTask '{0}' '{1}' '{2}'", jobId, taskId, filePath) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId, string.Format("cmd /c echo \"test\" > {0}", fileName)); - ScenarioTestHelpers.WaitForTaskCompletion(controller, context, jobId, taskId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId, string.Format("cmd /c echo \"test\" > {0}", fileName)); + ScenarioTestHelpers.WaitForTaskCompletion(this, context, jobId, taskId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-DeleteNodeFileByTask '{jobId}' '{taskId}' '{filePath}'" + ); } [Fact(Skip = "Successful re-recording, but fails in playback. See issue https://github.com/Azure/azure-powershell/issues/7512")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDeleteNodeFileByComputeNode() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string jobId = "deleteNodeFile"; string taskId = "task1"; string computeNodeId = null; string fileName = "testFile.txt"; string filePath = string.Format("workitems\\{0}\\job-1\\{1}\\wd\\{2}", jobId, taskId, fileName); - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-DeleteNodeFileByComputeNode '{0}' '{1}' '{2}'", poolId, computeNodeId, filePath) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId, string.Format("cmd /c echo \"test\" > {0}", fileName)); - ScenarioTestHelpers.WaitForTaskCompletion(controller, context, jobId, taskId); - computeNodeId = ScenarioTestHelpers.GetTaskComputeNodeId(controller, context, jobId, taskId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId, string.Format("cmd /c echo \"test\" > {0}", fileName)); + ScenarioTestHelpers.WaitForTaskCompletion(this, context, jobId, taskId); + computeNodeId = ScenarioTestHelpers.GetTaskComputeNodeId(this, context, jobId, taskId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-DeleteNodeFileByComputeNode '{poolId}' '{computeNodeId}' '{filePath}'" + ); } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/FileTests.ps1 b/src/Batch/Batch.Test/ScenarioTests/FileTests.ps1 index 54c672dcb137..dea55d267787 100644 --- a/src/Batch/Batch.Test/ScenarioTests/FileTests.ps1 +++ b/src/Batch/Batch.Test/ScenarioTests/FileTests.ps1 @@ -84,7 +84,7 @@ Tests downloading a Remote Desktop Protocol file #> function Test-GetRDPFile { - param([string]$poolId, [string]$computeNodeId) + param([string]$poolId) $context = New-Object Microsoft.Azure.Commands.Batch.Test.ScenarioTests.ScenarioTestContext $stream = New-Object System.IO.MemoryStream @@ -92,6 +92,9 @@ function Test-GetRDPFile try { + $computeNodes = Get-AzBatchComputeNode -PoolId $poolId -BatchContext $context + $computeNodeId = $computeNodes[0].Id + $computeNode = Get-AzBatchComputeNode -PoolId $poolId -Id $computeNodeId -BatchContext $context $computeNode | Get-AzBatchRemoteDesktopProtocolFile -BatchContext $context -DestinationStream $stream diff --git a/src/Batch/Batch.Test/ScenarioTests/JobScheduleTests.cs b/src/Batch/Batch.Test/ScenarioTests/JobScheduleTests.cs index 14c2a063cd80..ff8fee5da20f 100644 --- a/src/Batch/Batch.Test/ScenarioTests/JobScheduleTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/JobScheduleTests.cs @@ -12,28 +12,23 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class JobScheduleTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class JobScheduleTests : BatchTestRunner { - public XunitTracingInterceptor _logger; - - public JobScheduleTests(Xunit.Abstractions.ITestOutputHelper output) + public JobScheduleTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobScheduleCRUD() { - BatchController.NewInstance.RunPsTest(_logger, "Test-JobScheduleCRUD"); + TestRunner.RunTestScript("Test-JobScheduleCRUD"); } @@ -41,24 +36,22 @@ public void TestJobScheduleCRUD() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDisableEnableTerminateJobSchedule() { - BatchController controller = BatchController.NewInstance; string jobScheduleId = "testDisableEnableTerminateJobSchedule"; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-DisableEnableTerminateJobSchedule '{0}'", jobScheduleId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJobSchedule(controller, context, jobScheduleId, null); + ScenarioTestHelpers.CreateTestJobSchedule(this, context, jobScheduleId, null); }, () => { - ScenarioTestHelpers.DeleteJobSchedule(controller, context, jobScheduleId); + ScenarioTestHelpers.DeleteJobSchedule(this, context, jobScheduleId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-DisableEnableTerminateJobSchedule '{jobScheduleId}'" + ); } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/JobTests.cs b/src/Batch/Batch.Test/ScenarioTests/JobTests.cs index 5bb69e7a3f42..a5733c422356 100644 --- a/src/Batch/Batch.Test/ScenarioTests/JobTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/JobTests.cs @@ -13,28 +13,23 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Batch.Models; -using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.ScenarioTest; -using System.Reflection; using Xunit; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class JobTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class JobTests : BatchTestRunner { - public XunitTracingInterceptor _logger; - - public JobTests(Xunit.Abstractions.ITestOutputHelper output) + public JobTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCRUD() { - BatchController.NewInstance.RunPsTest(_logger, "Test-JobCRUD"); + TestRunner.RunTestScript("Test-JobCRUD"); } @@ -42,49 +37,43 @@ public void TestJobCRUD() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDisableEnableTerminateJob() { - BatchController controller = BatchController.NewInstance; string jobId = "testDisableEnableTerminateJob"; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-DisableEnableTerminateJob '{0}'", jobId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-DisableEnableTerminateJob '{jobId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void IfJobSetsAutoFailure_ItCompletesWhenAnyTaskFails() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string poolId = "testPool"; string jobId = "testJobCompletesWhenTaskFails"; string taskId = "taskId-1"; PSCloudJob completedJob = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("IfJobSetsAutoFailure-ItCompletesWhenAnyTaskFails '{0}' '{1}' '{2}'", poolId, jobId, taskId) }; }, - null, - () => + TestRunner.RunTestScript( + mockContext => { context = new ScenarioTestContext(); - completedJob = ScenarioTestHelpers.WaitForJobCompletion(controller, context, jobId, taskId); + completedJob = ScenarioTestHelpers.WaitForJobCompletion(this, context, jobId, taskId); AssertJobIsCompleteDueToTaskFailure(completedJob); - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"IfJobSetsAutoFailure-ItCompletesWhenAnyTaskFails '{poolId}' '{jobId}' '{taskId}'" + ); } private void AssertJobIsCompleteDueToTaskFailure(PSCloudJob job) diff --git a/src/Batch/Batch.Test/ScenarioTests/PoolTests.cs b/src/Batch/Batch.Test/ScenarioTests/PoolTests.cs index 41f2b47486cf..7a74889abd3e 100644 --- a/src/Batch/Batch.Test/ScenarioTests/PoolTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/PoolTests.cs @@ -12,78 +12,70 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class PoolTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class PoolTests : BatchTestRunner { private const string testPoolId = ScenarioTestHelpers.SharedPool; // Get from WATaskOSFamilyVersions table, which lags behind https://azure.microsoft.com/en-us/documentation/articles/cloud-services-guestos-update-matrix/ private const string specificOSVersion = "WA-GUEST-OS-4.56_201807-02"; - public XunitTracingInterceptor _logger; - public PoolTests(Xunit.Abstractions.ITestOutputHelper output) + public PoolTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestPoolCRUD() { - BatchController.NewInstance.RunPsTest(_logger, "Test-PoolCRUD"); + TestRunner.RunTestScript("Test-PoolCRUD"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestResizeAndStopResizePool() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string poolId = "resizePool"; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-ResizeAndStopResizePool '{0}'", poolId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestPool(controller, context, poolId, targetDedicated: 0, targetLowPriority: 0); + ScenarioTestHelpers.CreateTestPool(this, context, poolId, targetDedicated: 0, targetLowPriority: 0); }, () => { - ScenarioTestHelpers.DeletePool(controller, context, poolId); + ScenarioTestHelpers.DeletePool(this, context, poolId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-ResizeAndStopResizePool '{poolId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAutoScaleActions() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string poolId = "autoscalePool"; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-AutoScaleActions '{0}'", poolId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestPool(controller, context, poolId, targetDedicated: 0, targetLowPriority: 0); + ScenarioTestHelpers.CreateTestPool(this, context, poolId, targetDedicated: 0, targetLowPriority: 0); }, () => { - ScenarioTestHelpers.DeletePool(controller, context, poolId); + ScenarioTestHelpers.DeletePool(this, context, poolId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-AutoScaleActions '{poolId}'" + ); } } } diff --git a/src/Batch/Batch.Test/ScenarioTests/ScenarioTestContext.cs b/src/Batch/Batch.Test/ScenarioTests/ScenarioTestContext.cs index acd8e27b3e17..20aca1326b42 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ScenarioTestContext.cs +++ b/src/Batch/Batch.Test/ScenarioTests/ScenarioTestContext.cs @@ -24,11 +24,11 @@ public class ScenarioTestContext : BatchAccountContext public ScenarioTestContext() : base(null) { // Only set the properties needed for interacting with the Batch service. - this.AccountName = BatchController.BatchAccount; - this.PrimaryAccountKey = BatchController.BatchAccountKey; - this.TaskTenantUrl = BatchController.BatchAccountUrl; - this.ResourceGroupName = BatchController.BatchResourceGroup; - this.Subscription = BatchController.Subscription; + this.AccountName = BatchTestRunner.BatchAccount; + this.PrimaryAccountKey = BatchTestRunner.BatchAccountKey; + this.TaskTenantUrl = BatchTestRunner.BatchAccountUrl; + this.ResourceGroupName = BatchTestRunner.BatchResourceGroup; + this.Subscription = BatchTestRunner.Subscription; } protected override BatchServiceClient CreateBatchRestClient(string url, ServiceClientCredentials credentials, DelegatingHandler handler = default(DelegatingHandler)) diff --git a/src/Batch/Batch.Test/ScenarioTests/ScenarioTestHelpers.cs b/src/Batch/Batch.Test/ScenarioTests/ScenarioTestHelpers.cs index 982649498d7d..c525aa81f9c5 100644 --- a/src/Batch/Batch.Test/ScenarioTests/ScenarioTestHelpers.cs +++ b/src/Batch/Batch.Test/ScenarioTests/ScenarioTestHelpers.cs @@ -72,12 +72,12 @@ public static class ScenarioTestHelpers /// /// Creates an account and resource group for use with the Scenario tests /// - public static BatchAccountContext CreateTestAccountAndResourceGroup(BatchController controller, string resourceGroupName, string accountName, string location) + public static BatchAccountContext CreateTestAccountAndResourceGroup(BatchTestRunner runner, string resourceGroupName, string accountName, string location) { - controller.ResourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, new ResourceGroup() { Location = location }); - BatchAccount createResponse = controller.BatchManagementClient.BatchAccount.Create(resourceGroupName, accountName, new BatchAccountCreateParameters() { Location = location }); + runner.ResourceManagementClient.ResourceGroups.CreateOrUpdate(resourceGroupName, new ResourceGroup() { Location = location }); + BatchAccount createResponse = runner.BatchManagementClient.BatchAccount.Create(resourceGroupName, accountName, new BatchAccountCreateParameters() { Location = location }); BatchAccountContext context = BatchAccountContext.ConvertAccountResourceToNewAccountContext(createResponse, null); - BatchAccountKeys response = controller.BatchManagementClient.BatchAccount.GetKeys(resourceGroupName, accountName); + BatchAccountKeys response = runner.BatchManagementClient.BatchAccount.GetKeys(resourceGroupName, accountName); context.PrimaryAccountKey = response.Primary; context.SecondaryAccountKey = response.Secondary; return context; @@ -86,18 +86,18 @@ public static BatchAccountContext CreateTestAccountAndResourceGroup(BatchControl /// /// Cleans up an account and resource group used in a Scenario test. /// - public static void CleanupTestAccount(BatchController controller, string resourceGroupName, string accountName) + public static void CleanupTestAccount(BatchTestRunner runner, string resourceGroupName, string accountName) { - controller.BatchManagementClient.BatchAccount.Delete(resourceGroupName, accountName); - controller.ResourceManagementClient.ResourceGroups.Delete(resourceGroupName); + runner.BatchManagementClient.BatchAccount.Delete(resourceGroupName, accountName); + runner.ResourceManagementClient.ResourceGroups.Delete(resourceGroupName); } /// /// Adds a test certificate for use in Scenario tests. Returns the thumbprint of the cert. /// - public static string AddTestCertificate(BatchController controller, BatchAccountContext context, string filePath) + public static string AddTestCertificate(BatchTestRunner runner, BatchAccountContext context, string filePath) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); X509Certificate2 cert = new X509Certificate2(filePath); ListCertificateOptions getParameters = new ListCertificateOptions(context) @@ -145,9 +145,9 @@ public static string AddTestCertificate(BatchController controller, BatchAccount /// /// Deletes a certificate. /// - public static void DeleteTestCertificate(BatchController controller, BatchAccountContext context, string thumbprintAlgorithm, string thumbprint) + public static void DeleteTestCertificate(BatchTestRunner runner, BatchAccountContext context, string thumbprintAlgorithm, string thumbprint) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); CertificateOperationParameters parameters = new CertificateOperationParameters(context, thumbprintAlgorithm, thumbprint); @@ -158,9 +158,9 @@ public static void DeleteTestCertificate(BatchController controller, BatchAccoun /// /// Deletes a certificate. /// - public static void WaitForCertificateToFailDeletion(BatchController controller, BatchAccountContext context, string thumbprintAlgorithm, string thumbprint) + public static void WaitForCertificateToFailDeletion(BatchTestRunner runner, BatchAccountContext context, string thumbprintAlgorithm, string thumbprint) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListCertificateOptions parameters = new ListCertificateOptions(context) { @@ -186,7 +186,7 @@ public static void WaitForCertificateToFailDeletion(BatchController controller, /// Creates a test pool for use in Scenario tests. /// public static void CreateTestPool( - BatchController controller, + BatchTestRunner runner, BatchAccountContext context, string poolId, int? targetDedicated, @@ -218,14 +218,14 @@ public static void CreateTestPool( InterComputeNodeCommunicationEnabled = true }; - CreatePoolIfNotExists(controller, parameters); + CreatePoolIfNotExists(runner, parameters); } public static void CreatePoolIfNotExists( - BatchController controller, + BatchTestRunner runner, NewPoolParameters poolParameters) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); try { @@ -243,9 +243,9 @@ public static void CreatePoolIfNotExists( /// /// Creates an MPI pool. /// - public static void CreateMpiPoolIfNotExists(BatchController controller, BatchAccountContext context, int targetDedicated = 3) + public static void CreateMpiPoolIfNotExists(BatchTestRunner runner, BatchAccountContext context, int targetDedicated = 3) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListPoolOptions listOptions = new ListPoolOptions(context) { PoolId = MpiPoolId @@ -266,12 +266,12 @@ public static void CreateMpiPoolIfNotExists(BatchController controller, BatchAcc // We got the pool not found error, so continue and create the pool } - CreateTestPool(controller, context, MpiPoolId, targetDedicated, targetLowPriority: 0); + CreateTestPool(runner, context, MpiPoolId, targetDedicated, targetLowPriority: 0); } - public static void WaitForSteadyPoolAllocation(BatchController controller, BatchAccountContext context, string poolId) + public static void WaitForSteadyPoolAllocation(BatchTestRunner runner, BatchAccountContext context, string poolId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListPoolOptions options = new ListPoolOptions(context) { @@ -294,9 +294,9 @@ public static void WaitForSteadyPoolAllocation(BatchController controller, Batch /// /// Gets the number of pools under the specified account /// - public static int GetPoolCount(BatchController controller, BatchAccountContext context) + public static int GetPoolCount(BatchTestRunner runner, BatchAccountContext context) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListPoolOptions options = new ListPoolOptions(context); @@ -307,9 +307,9 @@ public static int GetPoolCount(BatchController controller, BatchAccountContext c /// /// Deletes a pool used in a Scenario test. /// - public static void DeletePool(BatchController controller, BatchAccountContext context, string poolId) + public static void DeletePool(BatchTestRunner runner, BatchAccountContext context, string poolId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); client.DeletePool(context, poolId); } @@ -317,9 +317,9 @@ public static void DeletePool(BatchController controller, BatchAccountContext co /// /// Creates a test job schedule for use in Scenario tests. /// - public static void CreateTestJobSchedule(BatchController controller, BatchAccountContext context, string jobScheduleId, TimeSpan? recurrenceInterval) + public static void CreateTestJobSchedule(BatchTestRunner runner, BatchAccountContext context, string jobScheduleId, TimeSpan? recurrenceInterval) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); PSJobSpecification jobSpecification = new PSJobSpecification(); jobSpecification.PoolInformation = new PSPoolInformation(); @@ -343,9 +343,9 @@ public static void CreateTestJobSchedule(BatchController controller, BatchAccoun /// /// Creates a test job for use in Scenario tests. /// - public static void CreateTestJob(BatchController controller, BatchAccountContext context, string jobId, string poolId = SharedPool) + public static void CreateTestJob(BatchTestRunner runner, BatchAccountContext context, string jobId, string poolId = SharedPool) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); PSPoolInformation poolInfo = new PSPoolInformation(); poolInfo.PoolId = poolId; @@ -361,10 +361,10 @@ public static void CreateTestJob(BatchController controller, BatchAccountContext /// /// Waits for a recent job on a job schedule and returns its id. If a previous job is specified, this method waits until a new job is created. /// - public static string WaitForRecentJob(BatchController controller, BatchAccountContext context, string jobScheduleId, string previousJob = null) + public static string WaitForRecentJob(BatchTestRunner runner, BatchAccountContext context, string jobScheduleId, string previousJob = null) { DateTime timeout = DateTime.Now.Add(GetTimeout(TimeSpan.FromMinutes(2))); - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListJobScheduleOptions options = new ListJobScheduleOptions(context) { @@ -389,9 +389,9 @@ public static string WaitForRecentJob(BatchController controller, BatchAccountCo /// /// Creates a test task for use in Scenario tests. /// - public static void CreateTestTask(BatchController controller, BatchAccountContext context, string jobId, string taskId, string cmdLine = "cmd /c dir /s", int numInstances = 0) + public static void CreateTestTask(BatchTestRunner runner, BatchAccountContext context, string jobId, string taskId, string cmdLine = "cmd /c dir /s", int numInstances = 0) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); PSMultiInstanceSettings multiInstanceSettings = null; if (numInstances > 1) @@ -412,9 +412,9 @@ public static void CreateTestTask(BatchController controller, BatchAccountContex /// /// Waits for the specified task to complete /// - public static void WaitForTaskCompletion(BatchController controller, BatchAccountContext context, string jobId, string taskId) + public static void WaitForTaskCompletion(BatchTestRunner runner, BatchAccountContext context, string jobId, string taskId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListTaskOptions options = new ListTaskOptions(context, jobId, null) { @@ -433,9 +433,9 @@ public static void WaitForTaskCompletion(BatchController controller, BatchAccoun /// /// Waits for the job to complete /// - public static PSCloudJob WaitForJobCompletion(BatchController controller, BatchAccountContext context, string jobId, string taskId) + public static PSCloudJob WaitForJobCompletion(BatchTestRunner runner, BatchAccountContext context, string jobId, string taskId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); PSCloudJob job = client.ListJobs(new ListJobOptions(context)).First(cloudJob => cloudJob.Id == jobId); @@ -454,9 +454,9 @@ public static PSCloudJob WaitForJobCompletion(BatchController controller, BatchA /// /// Gets the id of the compute node that the specified task completed on. Returns null if the task isn't complete. /// - public static string GetTaskComputeNodeId(BatchController controller, BatchAccountContext context, string jobId, string taskId) + public static string GetTaskComputeNodeId(BatchTestRunner runner, BatchAccountContext context, string jobId, string taskId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListTaskOptions options = new ListTaskOptions(context, jobId, null) { @@ -470,9 +470,9 @@ public static string GetTaskComputeNodeId(BatchController controller, BatchAccou /// /// Deletes a job schedule used in a Scenario test. /// - public static void DeleteJobSchedule(BatchController controller, BatchAccountContext context, string jobScheduleId) + public static void DeleteJobSchedule(BatchTestRunner runner, BatchAccountContext context, string jobScheduleId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); client.DeleteJobSchedule(context, jobScheduleId); } @@ -480,9 +480,9 @@ public static void DeleteJobSchedule(BatchController controller, BatchAccountCon /// /// Deletes a job used in a Scenario test. /// - public static void DeleteJob(BatchController controller, BatchAccountContext context, string jobId) + public static void DeleteJob(BatchTestRunner runner, BatchAccountContext context, string jobId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); client.DeleteJob(context, jobId); } @@ -490,9 +490,9 @@ public static void DeleteJob(BatchController controller, BatchAccountContext con /// /// Terminates a job /// - public static void TerminateJob(BatchController controller, BatchAccountContext context, string jobId) + public static void TerminateJob(BatchTestRunner runner, BatchAccountContext context, string jobId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); TerminateJobParameters parameters = new TerminateJobParameters(context, jobId, null); @@ -502,9 +502,9 @@ public static void TerminateJob(BatchController controller, BatchAccountContext /// /// Gets the id of a compute node in the specified pool /// - public static string GetComputeNodeId(BatchController controller, BatchAccountContext context, string poolId, int index = 0) + public static string GetComputeNodeId(BatchTestRunner runner, BatchAccountContext context, string poolId, int index = 0) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListComputeNodeOptions options = new ListComputeNodeOptions(context, poolId, null); List computeNodes = client.ListComputeNodes(options).ToList(); @@ -514,9 +514,9 @@ public static string GetComputeNodeId(BatchController controller, BatchAccountCo /// /// Waits for a compute node to get to the idle state /// - public static void WaitForIdleComputeNode(BatchController controller, BatchAccountContext context, string poolId, string computeNodeId) + public static void WaitForIdleComputeNode(BatchTestRunner runner, BatchAccountContext context, string poolId, string computeNodeId) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ListComputeNodeOptions options = new ListComputeNodeOptions(context, poolId, null) { @@ -541,9 +541,9 @@ public static void WaitForIdleComputeNode(BatchController controller, BatchAccou /// /// Creates a compute node user for use in Scenario tests. /// - public static void CreateComputeNodeUser(BatchController controller, BatchAccountContext context, string poolId, string computeNodeId, string computeNodeUserName) + public static void CreateComputeNodeUser(BatchTestRunner runner, BatchAccountContext context, string poolId, string computeNodeId, string computeNodeUserName) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); NewComputeNodeUserParameters parameters = new NewComputeNodeUserParameters(context, poolId, computeNodeId, null) { @@ -557,9 +557,9 @@ public static void CreateComputeNodeUser(BatchController controller, BatchAccoun /// /// Deletes a compute node user for use in Scenario tests. /// - public static void DeleteComputeNodeUser(BatchController controller, BatchAccountContext context, string poolId, string computeNodeId, string computeNodeUserName) + public static void DeleteComputeNodeUser(BatchTestRunner runner, BatchAccountContext context, string poolId, string computeNodeId, string computeNodeUserName) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); ComputeNodeUserOperationParameters parameters = new ComputeNodeUserOperationParameters(context, poolId, computeNodeId, computeNodeUserName); @@ -569,13 +569,13 @@ public static void DeleteComputeNodeUser(BatchController controller, BatchAccoun /// /// Uploads an application package to Storage /// - public static ApplicationPackage CreateApplicationPackage(BatchController controller, BatchAccountContext context, string applicationName, string version, string filePath) + public static ApplicationPackage CreateApplicationPackage(BatchTestRunner runner, BatchAccountContext context, string applicationName, string version, string filePath) { ApplicationPackage applicationPackage = null; if (HttpMockServer.Mode == HttpRecorderMode.Record) { - applicationPackage = controller.BatchManagementClient.ApplicationPackage.Create( + applicationPackage = runner.BatchManagementClient.ApplicationPackage.Create( context.ResourceGroupName, context.AccountName, applicationName, @@ -595,9 +595,9 @@ public static ApplicationPackage CreateApplicationPackage(BatchController contro /// /// Deletes an application used in a Scenario test. /// - public static void DeleteApplication(BatchController controller, BatchAccountContext context, string applicationName) + public static void DeleteApplication(BatchTestRunner runner, BatchAccountContext context, string applicationName) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); client.DeleteApplication(context.ResourceGroupName, context.AccountName, applicationName); } @@ -605,9 +605,9 @@ public static void DeleteApplication(BatchController controller, BatchAccountCon /// /// Deletes an application package used in a Scenario test. /// - public static void DeleteApplicationPackage(BatchController controller, BatchAccountContext context, string applicationName, string version) + public static void DeleteApplicationPackage(BatchTestRunner runner, BatchAccountContext context, string applicationName, string version) { - BatchClient client = new BatchClient(controller.BatchManagementClient, controller.ResourceManagementClient); + BatchClient client = new BatchClient(runner.BatchManagementClient, runner.ResourceManagementClient); client.DeleteApplicationPackage(context.ResourceGroupName, context.AccountName, applicationName, version); } diff --git a/src/Batch/Batch.Test/ScenarioTests/TaskTests.cs b/src/Batch/Batch.Test/ScenarioTests/TaskTests.cs index b79a1b7127fb..d9bb46fc9d03 100644 --- a/src/Batch/Batch.Test/ScenarioTests/TaskTests.cs +++ b/src/Batch/Batch.Test/ScenarioTests/TaskTests.cs @@ -12,123 +12,110 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System.Reflection; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; -using Microsoft.Azure.ServiceManagement.Common.Models; namespace Microsoft.Azure.Commands.Batch.Test.ScenarioTests { - public class TaskTests : WindowsAzure.Commands.Test.Utilities.Common.RMTestBase + public class TaskTests : BatchTestRunner { - public XunitTracingInterceptor _logger; - - public TaskTests(Xunit.Abstractions.ITestOutputHelper output) + public TaskTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTaskCRUD() { - BatchController controller = BatchController.NewInstance; string jobId = "taskCrudJob"; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-TaskCRUD '{0}'", jobId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-TaskCRUD '{jobId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateTaskCollection() { - BatchController controller = BatchController.NewInstance; string jobId = "createTaskCollectionJob"; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-CreateTaskCollection '{0}'", jobId) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-CreateTaskCollection '{jobId}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTerminateTask() { - BatchController controller = BatchController.NewInstance; BatchAccountContext context = null; string jobId = "testTerminateTaskJob"; string taskId1 = "testTask1"; string taskId2 = "testTask2"; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-TerminateTask '{0}' '{1}' '{2}'", jobId, taskId1, taskId2) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId); + ScenarioTestHelpers.CreateTestJob(this, context, jobId); // Make the tasks long running so they can be terminated before they finish execution - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId1, "ping -t localhost -w 60"); - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId2, "ping -t localhost -w 60"); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId1, "ping -t localhost -w 60"); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId2, "ping -t localhost -w 60"); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-TerminateTask '{jobId}' '{taskId1}' '{taskId2}'" + ); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListAllSubtasks() { - BatchController controller = BatchController.NewInstance; string jobId = "listSubtaskJob"; string taskId = "testTask"; int numInstances = 3; BatchAccountContext context = null; - controller.RunPsTestWorkflow( - _logger, - () => { return new string[] { string.Format("Test-ListAllSubtasks '{0}' '{1}' '{2}'", jobId, taskId, numInstances) }; }, - () => + TestRunner.RunTestScript( + null, + mockContext => { context = new ScenarioTestContext(); - ScenarioTestHelpers.CreateMpiPoolIfNotExists(controller, context); - ScenarioTestHelpers.CreateTestJob(controller, context, jobId, ScenarioTestHelpers.MpiPoolId); - ScenarioTestHelpers.CreateTestTask(controller, context, jobId, taskId, "cmd /c hostname", numInstances); - ScenarioTestHelpers.WaitForTaskCompletion(controller, context, jobId, taskId); + ScenarioTestHelpers.CreateMpiPoolIfNotExists(this, context); + ScenarioTestHelpers.CreateTestJob(this, context, jobId, ScenarioTestHelpers.MpiPoolId); + ScenarioTestHelpers.CreateTestTask(this, context, jobId, taskId, "cmd /c hostname", numInstances); + ScenarioTestHelpers.WaitForTaskCompletion(this, context, jobId, taskId); }, () => { - ScenarioTestHelpers.DeleteJob(controller, context, jobId); + ScenarioTestHelpers.DeleteJob(this, context, jobId); }, - MethodBase.GetCurrentMethod().ReflectedType?.ToString(), - MethodBase.GetCurrentMethod().Name); + $"Test-ListAllSubtasks '{jobId}' '{taskId}' '{numInstances}'" + ); } } } diff --git a/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestController.cs b/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestController.cs deleted file mode 100644 index 9af1f3f28730..000000000000 --- a/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestController.cs +++ /dev/null @@ -1,63 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using System; -using System.Diagnostics; -using System.IO; -using System.Linq; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.Azure.ServiceManagement.Common.Models; - -namespace Microsoft.Azure.Commands.UsageAggregates.Test.ScenarioTests -{ - // This TestController class called EnvironmentSetupHelper.SetupSomeOfManagementClients() method. - public sealed class UsageAggregatesTestController - { - private readonly EnvironmentSetupHelper _helper; - - public static UsageAggregatesTestController NewInstance => new UsageAggregatesTestController(); - - public UsageAggregatesTestController() - { - _helper = new EnvironmentSetupHelper(); - } - - public void RunPsTest(XunitTracingInterceptor logger, params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - _helper.TracingInterceptor = logger; - - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (MockContext.Start(callingClassType, mockName)) - { - _helper.SetupSomeOfManagementClients(); - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - var callingClassName = callingClassType?.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries).Last(); - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.GetRMModulePath(@"AzureRM.Billing.psd1")); - - _helper.RunPowerShellTest(scripts); - } - } - } -} diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServicesTestController.cs b/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestRunner.cs similarity index 53% rename from src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServicesTestController.cs rename to src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestRunner.cs index ed1da1c37ec5..d97f92eccc33 100644 --- a/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServicesTestController.cs +++ b/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTestRunner.cs @@ -12,24 +12,26 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.Azure.Management.MachineLearning.WebServices; +using Microsoft.Azure.Commands.TestFx; +using Xunit.Abstractions; -namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests +namespace Microsoft.Azure.Commands.UsageAggregates.Test.ScenarioTests { - public class WebServicesTestController : BaseTestController + public class UsageAggregatesTestRunner { - public static WebServicesTestController NewInstance - { - get - { - return new WebServicesTestController(); - } - } + protected readonly ITestRunner TestRunner; - protected override AzureMLWebServicesManagementClient ConstructServiceClient(MockContext context) + protected UsageAggregatesTestRunner(ITestOutputHelper output) { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); + TestRunner = TestManager.CreateInstance(output) + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithProjectSubfolderForTests("ScenarioTests") + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + helper.GetRMModulePath("Az.Billing.psd1") + }) + .Build(); } } } diff --git a/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTests.cs b/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTests.cs index 3833dc18f08c..c12bb4e99b7a 100644 --- a/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTests.cs +++ b/src/Billing/UsageAggregates.Test/ScenarioTests/UsageAggregatesTests.cs @@ -12,29 +12,24 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; using Xunit; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.UsageAggregates.Test.ScenarioTests { - public class UsageAggregatesTests : RMTestBase + public class UsageAggregatesTests : UsageAggregatesTestRunner { - public XunitTracingInterceptor _logger; - - public UsageAggregatesTests(ITestOutputHelper output) + public UsageAggregatesTests(ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetUsageAggregatesWithDefaultParameters() { - UsageAggregatesTestController.NewInstance.RunPsTest(_logger, "Test-GetUsageAggregatesWithDefaultParameters"); + TestRunner.RunTestScript("Test-GetUsageAggregatesWithDefaultParameters"); } } } diff --git a/src/Compute/Compute.Test/ScenarioTests/ComputeTestRunner.cs b/src/Compute/Compute.Test/ScenarioTests/ComputeTestRunner.cs index 97ca15ab4f6e..9dfa24f7921e 100644 --- a/src/Compute/Compute.Test/ScenarioTests/ComputeTestRunner.cs +++ b/src/Compute/Compute.Test/ScenarioTests/ComputeTestRunner.cs @@ -25,7 +25,7 @@ public class ComputeTestRunner protected ComputeTestRunner(ITestOutputHelper output) { - TestRunner = TestFx.TestManager.CreateInstance (output) + TestRunner = TestManager.CreateInstance (output) .WithNewPsScriptFilename ($"{GetType().Name}.ps1") .WithProjectSubfolderForTests ("ScenarioTests") .WithCommonPsScripts (new[] @@ -44,10 +44,6 @@ protected ComputeTestRunner(ITestOutputHelper output) helper.GetRMModulePath(@"Az.ManagedServiceIdentity.psd1"), }) - .WithRecordMatcher( - (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => - new PermissiveRecordMatcherWithApiExclusion(ignoreResourcesClient, resourceProviders, userAgentsToIgnore) - ) .WithNewRecordMatcherArguments ( userAgentsToIgnore: new Dictionary { diff --git a/src/CosmosDB/CosmosDB.Test/ScenarioTests/CosmosDBTestHelper.cs b/src/CosmosDB/CosmosDB.Test/ScenarioTests/CosmosDBTestHelper.cs deleted file mode 100644 index 1660d913b198..000000000000 --- a/src/CosmosDB/CosmosDB.Test/ScenarioTests/CosmosDBTestHelper.cs +++ /dev/null @@ -1,144 +0,0 @@ - -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using System.Threading.Tasks; -using System.Net.Http; -using Microsoft.Azure.Management.Internal.Resources; -using Microsoft.Azure.Management.Network; -using Microsoft.Azure.Commands.Common.KeyVault.Version2016_10_1; -using Microsoft.Azure.Commands.Common.KeyVault.Version2016_10_1.Models; -using Microsoft.Azure.KeyVault; -using Microsoft.Azure.KeyVault.WebKey; - -namespace Microsoft.Azure.Commands.CosmosDB.Test.ScenarioTests.ScenarioTest -{ - public class CosmosDBTestHelper - { - public static KeyVaultManagementClient KeyVaultManagementClient { get; set; } - public static KeyVaultClient KeyVaultClient { get; set; } - - public CosmosDBTestHelper(KeyVaultManagementClient keyVaultManagementClient, KeyVaultClient keyVaultClient) - { - KeyVaultManagementClient = keyVaultManagementClient; - KeyVaultClient = keyVaultClient; - } - - /// - /// Get access token - /// - /// - /// - /// - /// - public static async Task GetAccessToken(string authority, string resource, string scope) - { - string accessToken = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var context = new AuthenticationContext(authority, TokenCache.DefaultShared); - string authClientId = GetServicePrincipalId(); - string authSecret = GetServicePrincipalSecret(); - var clientCredential = new ClientCredential(authClientId, authSecret); - var result = await context.AcquireTokenAsync(resource, clientCredential).ConfigureAwait(false); - accessToken = result.AccessToken; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - accessToken = "fake-token"; - } - - return accessToken; - } - - /// - /// Get delegating handlers - /// - /// - public static DelegatingHandler[] GetHandlers() - { - HttpMockServer server = HttpMockServer.CreateInstance(); - return new DelegatingHandler[] { server }; - } - - /// - /// Get service principal Id from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalId() - { - string servicePrincipalId = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey] = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.ServicePrincipalKey); - servicePrincipalId = HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey]; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalId = HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey]; - } - return servicePrincipalId; - } - - /// - /// Get service principal secret from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalSecret() - { - string servicePrincipalSecret = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - servicePrincipalSecret = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.ServicePrincipalSecretKey); - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalSecret = "xyz"; - } - return servicePrincipalSecret; - } - - /// - /// Get service principal object id from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalObjectId() - { - string servicePrincipalObjectId = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey] = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.AADClientIdKey); - servicePrincipalObjectId = HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey]; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalObjectId = HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey]; - } - return servicePrincipalObjectId; - } - - /// - /// Generates a new key using KeyVaultClient. - /// - /// - public static KeyIdentifier CreateKeyVaultKey(Vault vault, string keyName) - { - string vaultUri = vault.Properties.VaultUri; - var createdKey = KeyVaultClient.CreateKeyAsync(vaultUri, keyName, JsonWebKeyType.Rsa, - keyOps: JsonWebKeyOperation.AllOperations).GetAwaiter().GetResult(); - return new KeyIdentifier(createdKey.Key.Kid); - } - - /// - /// Get Vault using KeyVaultManagementClient. - /// - /// - public static Vault GetAzureKeyVault(string resourceGroupName, string vaultName) - { - return KeyVaultManagementClient.Vaults.Get(resourceGroupName, vaultName); - } - } -} diff --git a/src/DataBoxEdge/DataBoxEdge.Test/ScenarioTests/DataBoxEdgeTestRunner.cs b/src/DataBoxEdge/DataBoxEdge.Test/ScenarioTests/DataBoxEdgeTestRunner.cs index 1a2fe6854c59..d389642b9bb8 100644 --- a/src/DataBoxEdge/DataBoxEdge.Test/ScenarioTests/DataBoxEdgeTestRunner.cs +++ b/src/DataBoxEdge/DataBoxEdge.Test/ScenarioTests/DataBoxEdgeTestRunner.cs @@ -17,7 +17,6 @@ using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using ResourceManagementClient = Microsoft.Azure.Management.Internal.Resources.ResourceManagementClient; using StorageManagementClient = Microsoft.Azure.Management.Storage.Version2017_10_01.StorageManagementClient; -using TestEnvironmentFactory = Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestEnvironmentFactory; using Microsoft.Azure.Commands.TestFx; using Xunit.Abstractions; diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlMockContext.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlMockContext.cs deleted file mode 100644 index 8d2eaee98696..000000000000 --- a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlMockContext.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using System.Net.Http; - -namespace Microsoft.Azure.Commands.DataLake.Test.ScenarioTests -{ - /// - /// This class is needed because MockContext does not expose AddHandlers api. And we need to call - /// that api to get the mock handlers and pass in to our ADLS client - /// - public class AdlMockContext : MockContext - { - public new static MockContext Start( - string className, - [System.Runtime.CompilerServices.CallerMemberName] - string methodName= "testframework_failed") - { - var context = new AdlMockContext(); - if (HttpMockServer.FileSystemUtilsObject == null) - { - HttpMockServer.FileSystemUtilsObject = new Microsoft.Azure.Test.HttpRecorder.FileSystemUtils(); - } - HttpMockServer.Initialize(className, methodName); - if (HttpMockServer.Mode != HttpRecorderMode.Playback) - { - context.disposed = false; - } - - return context; - } - - public DelegatingHandler[] GetDelegatingHAndlersForDataPlane(TestEnvironment currentEnvironment, - params DelegatingHandler[] existingHandlers) - { - return base.AddHandlers(currentEnvironment, existingHandlers); - } - } -} diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsAliasTests.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsAliasTests.cs index 601fdf54d273..0f1f9eed3704 100644 --- a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsAliasTests.cs +++ b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsAliasTests.cs @@ -16,55 +16,57 @@ namespace Microsoft.Azure.Commands.DataLakeStore.Test.ScenarioTests { + using Microsoft.Azure.Commands.DataLake.Test.ScenarioTests; using Microsoft.WindowsAzure.Commands.ScenarioTest; using ServiceManagement.Common.Models; using System.IO; using System.Reflection; using Xunit; - public class AdlsAliasTests : AdlsTestsBase + public class AdlsAliasTests : DataLakeStoreTestRunner { - public XunitTracingInterceptor _logger; + private readonly string ResourceGroupLocation = "westus"; + private readonly string TestFileSystemPermissionResourceGroupLocation = "ukwest"; + private readonly string TestFileSystemResourceGroupLocation = "ukwest"; - public AdlsAliasTests(Xunit.Abstractions.ITestOutputHelper output) + public AdlsAliasTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsAccount() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreAccount -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreAccount -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsAccountTiers() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreAccountTiers -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreAccountTiers -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsFirewallRules() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFirewall -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFirewall -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsVirtualNetworkRules() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreVirtualNetwork -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreVirtualNetwork -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsTrustedIdProvider() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreTrustedIdProvider -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreTrustedIdProvider -location '{ResourceGroupLocation}'"); } [Fact] @@ -73,28 +75,28 @@ public void TestAdlsFileSystem() { var workingPath = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); var testLocation = Path.Combine(workingPath, "ScenarioTests", (this.GetType().Name + ".ps1")); - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFileSystem -fileToCopy '{0}' -location '{1}'", testLocation, AdlsTestsBase.TestFileSystemResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFileSystem -fileToCopy '{testLocation}' -location '{TestFileSystemResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsFileSystemPermissions() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFileSystemPermissions -location '{0}'", AdlsTestsBase.TestFileSystemPermissionResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFileSystemPermissions -location '{TestFileSystemPermissionResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestNegativeAdlsAccount() { - NewInstance.RunPsTest(_logger, string.Format("Test-NegativeDataLakeStoreAccount -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-NegativeDataLakeStoreAccount -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsEnumerateAndRestoreDeletedItem() { - NewInstance.RunPsTest(_logger, string.Format("Test-AdlsEnumerateAndRestoreDeletedItem -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-AdlsEnumerateAndRestoreDeletedItem -location '{ResourceGroupLocation}'"); } } } diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTests.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTests.cs index ca2f6720df5c..01806907510b 100644 --- a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTests.cs +++ b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTests.cs @@ -20,50 +20,52 @@ namespace Microsoft.Azure.Commands.DataLakeStore.Test.ScenarioTests using System.Reflection; using Xunit; using System.IO; + using Microsoft.Azure.Commands.DataLake.Test.ScenarioTests; - public class AdlsTests : AdlsTestsBase + public class AdlsTests : DataLakeStoreTestRunner { - public XunitTracingInterceptor _logger; + private readonly string ResourceGroupLocation = "westus"; + private readonly string TestFileSystemPermissionResourceGroupLocation = "ukwest"; + private readonly string TestFileSystemResourceGroupLocation = "ukwest"; - public AdlsTests(Xunit.Abstractions.ITestOutputHelper output) + public AdlsTests(Xunit.Abstractions.ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsFirewallRules() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFirewall -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFirewall -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsVirtualNetworkRules() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreVirtualNetwork -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreVirtualNetwork -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsTrustedIdProvider() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreTrustedIdProvider -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreTrustedIdProvider -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsAccount() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreAccount -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreAccount -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsAccountTiers() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreAccountTiers -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreAccountTiers -location '{ResourceGroupLocation}'"); } [Fact] @@ -72,28 +74,28 @@ public void TestAdlsFileSystem() { var workingPath = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); var testLocation = Path.Combine(workingPath, "ScenarioTests", (this.GetType().Name + ".ps1")); - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFileSystem -fileToCopy '{0}' -location '{1}'", testLocation, AdlsTestsBase.TestFileSystemResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFileSystem -fileToCopy '{testLocation}' -location '{TestFileSystemResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsFileSystemPermissions() { - NewInstance.RunPsTest(_logger, string.Format("Test-DataLakeStoreFileSystemPermissions -location '{0}'", AdlsTestsBase.TestFileSystemPermissionResourceGroupLocation)); + TestRunner.RunTestScript($"Test-DataLakeStoreFileSystemPermissions -location '{TestFileSystemPermissionResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestNegativeAdlsAccount() { - NewInstance.RunPsTest(_logger, string.Format("Test-NegativeDataLakeStoreAccount -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-NegativeDataLakeStoreAccount -location '{ResourceGroupLocation}'"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAdlsEnumerateAndRestoreDeletedItem() { - NewInstance.RunPsTest(_logger, string.Format("Test-EnumerateAndRestoreDataLakeStoreDeletedItem -location '{0}'", AdlsTestsBase.ResourceGroupLocation)); + TestRunner.RunTestScript($"Test-EnumerateAndRestoreDataLakeStoreDeletedItem -location '{ResourceGroupLocation}'"); } } } diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTestsBase.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTestsBase.cs deleted file mode 100644 index 81528b631711..000000000000 --- a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/AdlsTestsBase.cs +++ /dev/null @@ -1,168 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Management.Network; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using RestTestFramework = Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using TestEnvironmentFactory = Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestEnvironmentFactory; -using NewResourceManagementClient = Microsoft.Azure.Management.Internal.Resources.ResourceManagementClient; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; -using System.IO; -using Microsoft.Azure.Management.DataLake.Store; -using Microsoft.Azure.Commands.DataLakeStore.Models; -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Azure.Commands.DataLake.Test.ScenarioTests; - -namespace Microsoft.Azure.Commands.DataLakeStore.Test.ScenarioTests -{ - public class AdlsTestsBase : RMTestBase - { - private readonly EnvironmentSetupHelper _helper; - - internal const string ResourceGroupLocation = "westus"; - internal const string TestFileSystemPermissionResourceGroupLocation = "ukwest"; - internal const string TestFileSystemResourceGroupLocation = "ukwest"; - - public NewResourceManagementClient NewResourceManagementClient { get; private set; } - - public DataLakeStoreAccountManagementClient DataLakeStoreAccountManagementClient { get; private set; } - - public NetworkManagementClient NetworkClient { get; private set; } - - public static AdlsTestsBase NewInstance => new AdlsTestsBase(); - - - public AdlsTestsBase() - { - _helper = new EnvironmentSetupHelper(); - } - - public void RunPsTest(XunitTracingInterceptor logger, params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - _helper.TracingInterceptor = logger; - var newScripts = new List(scripts); - newScripts.Insert(0, "$ProgressPreference=\"SilentlyContinue\""); - - RunPsTestWorkflow( - () => newScripts.ToArray(), - // no custom cleanup - null, - callingClassType, - mockName); - } - - - public void RunPsTestWorkflow( - Func scriptBuilder, - Action cleanup, - string callingClassType, - string mockName) - { - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null}, - {"Microsoft.Network", null} - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new UrlDecodingRecordMatcher(true, d, providersToIgnore); - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (var context = AdlMockContext.Start(callingClassType, mockName)) - { - SetupManagementClients(context); - - // register the namespace. - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - var callingClassName = callingClassType.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries).Last(); - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.RMNetworkModule, - _helper.GetRMModulePath(@"AzureRM.DataLakeStore.psd1"), - "AzureRM.Resources.ps1"); - - try - { - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - _helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - ReSetDataLakeStoreFileSystemManagementClient(); - } - } - } - - private void SetupManagementClients(MockContext context) - { - DataLakeStoreAccountManagementClient = GetDataLakeStoreAccountManagementClient(context); - SetDataLakeStoreFileSystemManagementClient(context); - NewResourceManagementClient = GetNewResourceManagementClient(context); - NetworkClient = GetNetworkClient(context); - _helper.SetupManagementClients(NewResourceManagementClient, NetworkClient, DataLakeStoreAccountManagementClient); - } - - #region client creation helpers - - private static NewResourceManagementClient GetNewResourceManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static DataLakeStoreAccountManagementClient GetDataLakeStoreAccountManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static void ReSetDataLakeStoreFileSystemManagementClient() { AdlsClientFactory.IsTest = false; } - - private static void SetDataLakeStoreFileSystemManagementClient(MockContext context) - { - var currentEnvironment = TestEnvironmentFactory.GetTestEnvironment(); - AdlsClientFactory.IsTest = true; - AdlsClientFactory.CustomDelegatingHAndler = ((AdlMockContext)context).GetDelegatingHAndlersForDataPlane(currentEnvironment, new AdlMockDelegatingHandler()); - AdlsClientFactory.MockCredentials = currentEnvironment.TokenInfo[TokenAudience.Management]; - } - - protected NetworkManagementClient GetNetworkClient(MockContext context) - { - NetworkManagementClient client = - context.GetServiceClient( - TestEnvironmentFactory.GetTestEnvironment()); - return client; - } - #endregion - } -} diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/DataLakeStoreTestRunner.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/DataLakeStoreTestRunner.cs new file mode 100644 index 000000000000..2dc9a65c3948 --- /dev/null +++ b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/DataLakeStoreTestRunner.cs @@ -0,0 +1,73 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.DataLakeStore.Models; +using Microsoft.Azure.Commands.TestFx; +using System.Collections.Generic; +using Xunit.Abstractions; + +namespace Microsoft.Azure.Commands.DataLake.Test.ScenarioTests +{ + public class DataLakeStoreTestRunner + { + protected readonly ITestRunner TestRunner; + + protected DataLakeStoreTestRunner(ITestOutputHelper output) + { + TestRunner = TestManager.CreateInstance(output) + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithProjectSubfolderForTests("ScenarioTests") + .WithCommonPsScripts(new[] + { + @"Common.ps1", + @"../AzureRM.Resources.ps1", + }) + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + helper.RMNetworkModule, + helper.GetRMModulePath("Az.DataLakeStore.psd1") + }) + .WithNewRecordMatcherArguments( + userAgentsToIgnore: new Dictionary + { + {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} + }, + resourceProviders: new Dictionary + { + {"Microsoft.Resources", null}, + {"Microsoft.Features", null}, + {"Microsoft.Authorization", null}, + {"Microsoft.Network", null} + } + ) + .WithRecordMatcher( + (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => new UrlDecodingRecordMatcher(ignoreResourcesClient, resourceProviders, userAgentsToIgnore) + ) + .WithMockContextAction( + mockContext => + { + var currentEnvironment = TestEnvironmentFactory.GetTestEnvironment(); + AdlsClientFactory.IsTest = true; + AdlsClientFactory.CustomDelegatingHAndler = mockContext.AddHandlers(currentEnvironment, new AdlMockDelegatingHandler()); + AdlsClientFactory.MockCredentials = currentEnvironment.TokenInfo[TokenAudience.Management]; + } + ) + .WithCleanupAction( + () => AdlsClientFactory.IsTest = false + ) + .Build(); + } + } +} diff --git a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/UrlDecodingRecordMatcher.cs b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/UrlDecodingRecordMatcher.cs index b7a769bb438d..bdb2a1d3c000 100644 --- a/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/UrlDecodingRecordMatcher.cs +++ b/src/DataLakeStore/DataLakeStore.Test/ScenarioTests/UrlDecodingRecordMatcher.cs @@ -19,6 +19,7 @@ using System.Net.Http; using System.Text; using System.Text.RegularExpressions; +using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.WindowsAzure.Commands.ScenarioTest; diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/Common.ps1 b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/Common.ps1 index f2ba6dc70ce4..608495142e30 100644 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/Common.ps1 +++ b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/Common.ps1 @@ -14,83 +14,22 @@ <# .SYNOPSIS -Gets the location for the Lab. Default to West US if none found. +Gets valid resource group name #> -function Get-Location +function Get-ResourceGroupName { - if ([Microsoft.Azure.Test.HttpRecorder.HttpMockServer]::Mode -ne ` - [Microsoft.Azure.Test.HttpRecorder.HttpRecorderMode]::Playback) - { - $namespace = "Microsoft.DevTestLab" - $type = "sites" - $location = Get-AzResourceProvider -ProviderNamespace $namespace ` - | where {$_.ResourceTypes[0].ResourceTypeName -eq $type} + param([string] $prefix = [string]::Empty) - if ($location -eq $null) - { - return "West US" - } else - { - return $location.Locations[0] - } - } - - return "WestUS" -} - -<# -.SYNOPSIS -Invoke a script block twice, once with param1 and once with param2. -#> -function Invoke-For-Both -{ - Param($param1, - $param2, - [scriptblock]$functionToCall) - - $functionToCall.Invoke($param1); - $functionToCall.Invoke($param2); -} - -<# -.SYNOPSIS -Create a resource group and lab. -#> -function Setup-Test-ResourceGroup -{ - Param($_resourceGroupName, - $_labName) - $global:rgname = $_resourceGroupName; - $global:labName = $_labName; - - $location = Get-Location - - #Setup - New-AzResourceGroup -Name $rgname -Location $location - New-AzResourceGroupDeployment -Name $labName -ResourceGroupName $rgname ` - -TemplateParameterObject @{ newLabName = "$labName" } ` - -TemplateFile https://raw.githubusercontent.com/Azure/azure-devtestlab/master/Samples/101-dtl-create-lab/azuredeploy.json -} - -<# -.SYNOPSIS -Set global variables. -#> -function Setup-Test-Vars -{ - Param($_resourceGroupName, - $_labName) - $global:rgname = $_resourceGroupName; - $global:labName = $_labName; + return getAssetName $prefix } <# .SYNOPSIS -Destroy the lab resource group. +Gets valid resource name #> -function Destroy-Test-ResourceGroup +function Get-ResourceName { - Param($_resourceGroupName) + param([string] $prefix = [string]::Empty) - Remove-AzResourceGroup -Name $_resourceGroupName -Force + return getAssetName $prefix } diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsController.cs b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsController.cs deleted file mode 100644 index e24cc64e4421..000000000000 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsController.cs +++ /dev/null @@ -1,117 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Management.DevTestLabs; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using TestEnvironmentFactory = Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestEnvironmentFactory; - -namespace Microsoft.Azure.Commands.DevTestLabs.Test.ScenarioTests -{ - public class DevTestLabsController - { - private readonly EnvironmentSetupHelper _helper; - - public DevTestLabsClient DevTestLabsClient { get; private set; } - - public static DevTestLabsController NewInstance => new DevTestLabsController(); - - public DevTestLabsController() - { - _helper = new EnvironmentSetupHelper(); - } - - public void RunPsTest(params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - RunPsTestWorkflow( - () => scripts, - // no custom initializer - null, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void RunPsTestWorkflow( - Func scriptBuilder, - Action initialize, - Action cleanup, - string callingClassType, - string mockName) - { - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null} - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new PermissiveRecordMatcherWithApiExclusion(true, d, providersToIgnore); - - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (var context = MockContext.Start(callingClassType, mockName)) - { - initialize(); - SetupManagementClients(context); - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - var callingClassName = callingClassType.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries).Last(); - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.GetRMModulePath(@"AzureRM.DevTestLabs.psd1")); - - try - { - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - _helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - } - } - } - - private void SetupManagementClients(MockContext context) - { - DevTestLabsClient = GetDevTestLabsManagementClient(context); - _helper.SetupManagementClients(DevTestLabsClient); - } - - private static DevTestLabsClient GetDevTestLabsManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - } -} diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.cs b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.cs deleted file mode 100644 index 2ce28047eeeb..000000000000 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.cs +++ /dev/null @@ -1,85 +0,0 @@ -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; -using System; -using System.Diagnostics; -using System.Threading; - -namespace Microsoft.Azure.Commands.DevTestLabs.Test.ScenarioTests -{ - public class DevTestLabsTestFixture : RMTestBase, IDisposable - { - private string _resourceGroupName; - private string _labName; - private DevTestLabsController _controller; - - private SynchronizationContext _synchronizationContext; - - public DevTestLabsController Controller - { - get - { - Init(); - - return _controller; - } - } - - public void Init() - { - if (_resourceGroupName != null) - { - return; - } - - _synchronizationContext = SynchronizationContext.Current; - - _controller = DevTestLabsController.NewInstance; - - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - _controller.RunPsTestWorkflow( - () => new[] { "Setup-Test-ResourceGroup " + _resourceGroupName + " " + _labName }, - // custom initializer - () => - { - _resourceGroupName = GenerateName(); - _labName = GenerateName(); - }, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void RunTest(string testName) - { - var sf = new StackTrace().GetFrame(2); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - Init(); - var scripts = new[] { "Setup-Test-Vars " + _resourceGroupName + " " + _labName, testName }; - - Controller.RunPsTestWorkflow( - () => scripts, - // no custom initializer - null, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void Dispose() - { - SynchronizationContext.SetSynchronizationContext(_synchronizationContext); - _controller?.RunPsTest("Destroy-Test-ResourceGroup " + _resourceGroupName); - } - - private static string GenerateName() - { - return Microsoft.Azure.Test.HttpRecorder.HttpMockServer.GetAssetName("DevTestLabsTests", "onesdk"); - } - } -} \ No newline at end of file diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.ps1 b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.ps1 deleted file mode 100644 index 5f282702bb03..000000000000 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestFixture.ps1 +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestRunner.cs b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestRunner.cs new file mode 100644 index 000000000000..ac62faf7a39c --- /dev/null +++ b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/DevTestLabsTestRunner.cs @@ -0,0 +1,56 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using System; +using System.Collections.Generic; +using System.Text; +using Xunit.Abstractions; + +namespace Microsoft.Azure.Commands.DevTestLabs.Test.ScenarioTests +{ + public class DevTestLabsTestRunner + { + protected ITestRunner TestRunner; + + protected DevTestLabsTestRunner(ITestOutputHelper output) + { + TestRunner = TestManager.CreateInstance(output) + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithProjectSubfolderForTests("ScenarioTests") + .WithCommonPsScripts(new[] + { + @"Common.ps1", + }) + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + helper.GetRMModulePath("Az.DevTestLabs.psd1") + }) + .WithNewRecordMatcherArguments( + userAgentsToIgnore: new Dictionary + { + {"Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2016-02-01"} + }, + resourceProviders: new Dictionary + { + {"Microsoft.Resources", null}, + {"Microsoft.Features", null}, + {"Microsoft.Authorization", null} + } + ) + .Build(); + } + } +} diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.cs b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.cs index df34723c3800..f511d5a690df 100644 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.cs +++ b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.cs @@ -14,51 +14,51 @@ using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; +using Xunit.Sdk; namespace Microsoft.Azure.Commands.DevTestLabs.Test.ScenarioTests { - public class PolicyTests : IClassFixture + public class PolicyTests : DevTestLabsTestRunner { - private DevTestLabsTestFixture _fixture; - public PolicyTests(DevTestLabsTestFixture fixture) + public PolicyTests(TestOutputHelper output) : base(output) { - _fixture = fixture; + } [Fact(Skip = "New ResourceManager version. Needs re-recorded. DevTestLab tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6677")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAzureRmDtlVMsPerLabPolicy() { - _fixture.RunTest("Test-AzureRmDtlVMsPerLabPolicy"); + TestRunner.RunTestScript("Test-AzureRmDtlVMsPerLabPolicy"); } [Fact(Skip = "New ResourceManager version. Needs re-recorded. DevTestLab tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6677")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAzureRmDtlVMsPerUserPolicy() { - _fixture.RunTest("Test-AzureRmDtlVMsPerUserPolicy"); + TestRunner.RunTestScript("Test-AzureRmDtlVMsPerUserPolicy"); } [Fact(Skip = "New ResourceManager version. Needs re-recorded. DevTestLab tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6677")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAzureRmDtlAllowedVMSizesPolicy() { - _fixture.RunTest("Test-AzureRmDtlAllowedVMSizesPolicy"); + TestRunner.RunTestScript("Test-AzureRmDtlAllowedVMSizesPolicy"); } [Fact(Skip = "New ResourceManager version. Needs re-recorded. DevTestLab tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6677")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAzureRmDtlAutoShutdownPolicy() { - _fixture.RunTest("Test-AzureRmDtlAutoShutdownPolicy"); + TestRunner.RunTestScript("Test-AzureRmDtlAutoShutdownPolicy"); } [Fact(Skip = "New ResourceManager version. Needs re-recorded. DevTestLab tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6677")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAzureRmDtlAutoStartPolicy() { - _fixture.RunTest("Test-AzureRmDtlAutoStartPolicy"); + TestRunner.RunTestScript("Test-AzureRmDtlAutoStartPolicy"); } } } diff --git a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.ps1 b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.ps1 index 284acb9e9796..7e74ca86a404 100644 --- a/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.ps1 +++ b/src/DevTestLabs/DevTestLabs.Test/ScenarioTests/PolicyTests.ps1 @@ -18,15 +18,25 @@ Tests AzureRmDtlVMsPerLabPolicy #> function Test-AzDtlVMsPerLabPolicy { - # Max VMs per lab policy - $policy = Set-AzDtlVMsPerLabPolicy -MaxVMs 5 -LabName $labName -ResourceGroupName $rgname - $readBack = Get-AzDtlVMsPerLabPolicy -LabName $labName -ResourceGroupName $rgname + $rgName = Get-ResourceGroupName + $labName = Get-ResourceName "onesdk" - Invoke-For-Both $policy $readBack ` + try { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual "5" $x.Threshold + # Max VMs per lab policy + $policy = Set-AzDtlVMsPerLabPolicy -MaxVMs 5 -LabName $labName -ResourceGroupName $rgName + $readBack = Get-AzDtlVMsPerLabPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual "5" $policy.Threshold + + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual "5" $readBack.Threshold + + } + finally + { + Clean-ResourceGroup $rgName } } @@ -36,13 +46,23 @@ Tests AzureRmDtlVMsPerUserPolicy #> function Test-AzDtlVMsPerUserPolicy { - $policy = Set-AzDtlVMsPerUserPolicy -MaxVMs 5 -LabName $labName -ResourceGroupName $rgname - $readBack = Get-AzDtlVMsPerUserPolicy -LabName $labName -ResourceGroupName $rgname - Invoke-For-Both $policy $readBack ` + $rgName = Get-ResourceGroupName + $labName = Get-ResourceName "onesdk" + + try { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual "5" $x.Threshold + $policy = Set-AzDtlVMsPerUserPolicy -MaxVMs 5 -LabName $labName -ResourceGroupName $rgName + $readBack = Get-AzDtlVMsPerUserPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual "5" $policy.Threshold + + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual "5" $readBack.Threshold + } + finally + { + Clean-ResourceGroup $rgName } } @@ -52,13 +72,23 @@ Tests AzureRmDtlAllowedVMSizesPolicy #> function Test-AzDtlAllowedVMSizesPolicy { - $policy = Set-AzDtlAllowedVMSizesPolicy -Enable -LabName $labName -ResourceGroupName $rgname -VmSizes Standard_A3, Standard_A0 - $readBack = Get-AzDtlAllowedVMSizesPolicy -LabName $labName -ResourceGroupName $rgname - Invoke-For-Both $policy $readBack ` + $rgName = Get-ResourceGroupName + $labName = Get-ResourceName "onesdk" + + try + { + $policy = Set-AzDtlAllowedVMSizesPolicy -Enable -LabName $labName -ResourceGroupName $rgName -VmSizes Standard_A3, Standard_A0 + $readBack = Get-AzDtlAllowedVMSizesPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual '["Standard_A3","Standard_A0"]' $policy.Threshold + + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual '["Standard_A3","Standard_A0"]' $readBack.Threshold + } + finally { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual '["Standard_A3","Standard_A0"]' $x.Threshold + Clean-ResourceGroup $rgName } } @@ -68,13 +98,23 @@ Tests AzureRmDtlAllowedVMSizesPolicy #> function Test-AzDtlAutoShutdownPolicy { - $policy = Set-AzDtlAutoShutdownPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgname - $readBack = Get-AzDtlAutoShutdownPolicy -LabName $labName -ResourceGroupName $rgname - Invoke-For-Both $policy $readBack ` + $rgName = Get-ResourceGroupName + $labName = Get-ResourceName "onesdk" + + try + { + $policy = Set-AzDtlAutoShutdownPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgName + $readBack = Get-AzDtlAutoShutdownPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual "1330" $policy.DailyRecurrence.Time + + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual "1330" $readBack.DailyRecurrence.Time + } + finally { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual "1330" $x.DailyRecurrence.Time + Clean-ResourceGroup $rgName } } @@ -84,22 +124,33 @@ Tests AzureRmDtlAutoStartPolicy #> function Test-AzDtlAutoStartPolicy { - $policy = Set-AzDtlAutoStartPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgname - $readBack = Get-AzDtlAutoStartPolicy -LabName $labName -ResourceGroupName $rgname - Invoke-For-Both $policy $readBack ` + $rgName = Get-ResourceGroupName + $labName = Get-ResourceName "onesdk" + + try { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual "1330" $x.WeeklyRecurrence.Time - } + $policy = Set-AzDtlAutoStartPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgName + $readBack = Get-AzDtlAutoStartPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual "1330" $policy.WeeklyRecurrence.Time - $policy = Set-AzDtlAutoStartPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgname -Days Monday, Tuesday - $readBack = Get-AzDtlAutoStartPolicy -LabName $labName -ResourceGroupName $rgname - Invoke-For-Both $policy $readBack ` + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual "1330" $readBack.WeeklyRecurrence.Time + + $policy = Set-AzDtlAutoStartPolicy -Time "13:30:00" -LabName $labName -ResourceGroupName $rgName -Days Monday, Tuesday + $readBack = Get-AzDtlAutoStartPolicy -LabName $labName -ResourceGroupName $rgName + + Assert-AreEqual "Enabled" $policy.Status + Assert-AreEqual "1330" $policy.WeeklyRecurrence.Time + Assert-AreEqualArray ([System.DayOfWeek]::Monday, [System.DayOfWeek]::Tuesday) $policy.WeeklyRecurrence.Weekdays + + Assert-AreEqual "Enabled" $readBack.Status + Assert-AreEqual "1330" $readBack.WeeklyRecurrence.Time + Assert-AreEqualArray ([System.DayOfWeek]::Monday, [System.DayOfWeek]::Tuesday) $readBack.WeeklyRecurrence.Weekdays + } + finally { - Param($x) - Assert-AreEqual "Enabled" $x.Status - Assert-AreEqual "1330" $x.WeeklyRecurrence.Time - Assert-AreEqualArray ([System.DayOfWeek]::Monday, [System.DayOfWeek]::Tuesday) $x.WeeklyRecurrence.Weekdays + Clean-ResourceGroup $rgName } } diff --git a/src/EventHub/EventHub.Test/ScenarioTests/EventHubTestRunner.cs b/src/EventHub/EventHub.Test/ScenarioTests/EventHubTestRunner.cs index e29390c5d0aa..80f079e9cf3a 100644 --- a/src/EventHub/EventHub.Test/ScenarioTests/EventHubTestRunner.cs +++ b/src/EventHub/EventHub.Test/ScenarioTests/EventHubTestRunner.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using Microsoft.Azure.Commands.TestFx; +using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit.Abstractions; diff --git a/src/HDInsight/HDInsight.Test/ScenarioTests/TestHelper.cs b/src/HDInsight/HDInsight.Test/ScenarioTests/TestHelper.cs deleted file mode 100644 index e12198eba1f1..000000000000 --- a/src/HDInsight/HDInsight.Test/ScenarioTests/TestHelper.cs +++ /dev/null @@ -1,179 +0,0 @@ - -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.IdentityModel.Clients.ActiveDirectory; -using System.Threading.Tasks; -using System.Net.Http; -using Microsoft.Azure.Management.KeyVault; -using Microsoft.Azure.KeyVault; -using Microsoft.Azure.Management.HDInsight; -using Microsoft.Azure.Management.Internal.Resources; -using Microsoft.Azure.Management.OperationalInsights; -using Microsoft.Azure.Management.ManagedServiceIdentity; -using Microsoft.Azure.Management.KeyVault.Models; -using Microsoft.Azure.KeyVault.Models; -using Microsoft.Azure.KeyVault.WebKey; -using Microsoft.Azure.Management.Network.Models; -using System.Collections.Generic; -using Microsoft.Azure.Management.Network; - -namespace Commands.HDInsight.Test.ScenarioTests -{ - public class TestHelper - { - public static KeyVaultManagementClient KeyVaultManagementClient { get; set; } - public static KeyVaultClient KeyVaultClient { get; set; } - public static NetworkManagementClient NetworkManagementClient { get; set; } - - public TestHelper(KeyVaultManagementClient keyVaultManagementClient, KeyVaultClient keyVaultClient, NetworkManagementClient networkManagementClient) - { - KeyVaultManagementClient = keyVaultManagementClient; - KeyVaultClient = keyVaultClient; - NetworkManagementClient = networkManagementClient; - } - - /// - /// Get access token - /// - /// - /// - /// - /// - public static async Task GetAccessToken(string authority, string resource, string scope) - { - string accessToken = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var context = new AuthenticationContext(authority, TokenCache.DefaultShared); - string authClientId = GetServicePrincipalId(); - string authSecret = GetServicePrincipalSecret(); - var clientCredential = new ClientCredential(authClientId, authSecret); - var result = await context.AcquireTokenAsync(resource, clientCredential).ConfigureAwait(false); - accessToken = result.AccessToken; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - accessToken = "fake-token"; - } - - return accessToken; - } - - /// - /// Get delegating handlers - /// - /// - public static DelegatingHandler[] GetHandlers() - { - HttpMockServer server = HttpMockServer.CreateInstance(); - return new DelegatingHandler[] { server }; - } - - /// - /// Get service principal Id from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalId() - { - string servicePrincipalId = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey] = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.ServicePrincipalKey); - servicePrincipalId = HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey]; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalId = HttpMockServer.Variables[ConnectionStringKeys.ServicePrincipalKey]; - } - return servicePrincipalId; - } - - /// - /// Get service principal secret from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalSecret() - { - string servicePrincipalSecret = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - servicePrincipalSecret = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.ServicePrincipalSecretKey); - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalSecret = "xyz"; - } - return servicePrincipalSecret; - } - - /// - /// Get service principal object id from test configurations(Environment variables). - /// - /// - public static string GetServicePrincipalObjectId() - { - string servicePrincipalObjectId = null; - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey] = environment.ConnectionString.KeyValuePairs.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.AADClientIdKey); - servicePrincipalObjectId = HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey]; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - servicePrincipalObjectId = HttpMockServer.Variables[ConnectionStringKeys.AADClientIdKey]; - } - return servicePrincipalObjectId; - } - - /// - /// New key identity using KeyVaultClient. - /// - /// - public static KeyIdentifier GenerateVaultKey(Vault vault, string keyName) - { - string vaultUri = vault.Properties.VaultUri; - var attributes = new Microsoft.Azure.KeyVault.Models.KeyAttributes(); - var createdKey = KeyVaultClient.CreateKeyAsync(vaultUri, keyName, Microsoft.Azure.KeyVault.WebKey.JsonWebKeyType.Rsa, - keyOps: Microsoft.Azure.KeyVault.WebKey.JsonWebKeyOperation.AllOperations).GetAwaiter().GetResult(); - return new KeyIdentifier(createdKey.Key.Kid); - } - - /// - /// Get Vault using KeyVaultManagementClient. - /// - /// - public static Vault GetVault(string resourceGroupName, string vaultName) - { - return KeyVaultManagementClient.Vaults.Get(resourceGroupName, vaultName); - } - - public static VirtualNetwork CreateVirtualNetworkWithSubnet(string resourceGroupName, string location, string virtualNetworkName, string subnetName, bool subnetPrivateEndpointNetworkPoliciesFlag = true, bool subnetPrivateLinkServiceNetworkPoliciesFlag = true) - { - VirtualNetwork vnet = new VirtualNetwork() - { - Location = location, - AddressSpace = new AddressSpace() - { - AddressPrefixes = new List() - { - "10.0.0.0/16", - } - }, - Subnets = new List() - { - new Subnet() - { - Name = subnetName, - AddressPrefix = "10.0.0.0/24", - PrivateEndpointNetworkPolicies = subnetPrivateEndpointNetworkPoliciesFlag ? "Enabled" : "Disabled", - PrivateLinkServiceNetworkPolicies = subnetPrivateLinkServiceNetworkPoliciesFlag ? "Enabled" : "Disabled" - } - } - }; - return NetworkManagementClient.VirtualNetworks.CreateOrUpdate(resourceGroupName, virtualNetworkName, vnet); - } - } -} diff --git a/src/HPCCache/HPCCache.Test/Fixtures/HpcCacheTestContext.cs b/src/HPCCache/HPCCache.Test/Fixtures/HpcCacheTestContext.cs index 6b6b2d30b541..024cb569556f 100644 --- a/src/HPCCache/HPCCache.Test/Fixtures/HpcCacheTestContext.cs +++ b/src/HPCCache/HPCCache.Test/Fixtures/HpcCacheTestContext.cs @@ -16,9 +16,12 @@ namespace Microsoft.Azure.Commands.HPCCache.Test.Fixtures { using System; using System.Collections.Generic; + using System.IO; using System.Linq; + using System.Reflection; using Microsoft.Azure.Commands.HPCCache.Test.ScenarioTests; using Microsoft.Azure.Commands.HPCCache.Test.Utilities; + using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.Azure.Management.Authorization; using Microsoft.Azure.Management.Authorization.Models; using Microsoft.Azure.Management.Internal.Resources; @@ -61,7 +64,7 @@ public HpcCacheTestContext( [System.Runtime.CompilerServices.CallerMemberName] string methodName = ".ctor") { - HttpMockServer.Matcher = HpcCacheController.GetRecordMatcher(); + BuildMockServer(); this.mockContext = MockContext.Start(suiteObject, methodName); this.RegisterSubscriptionForResource("Microsoft.StorageCache"); } @@ -76,11 +79,43 @@ public HpcCacheTestContext( [System.Runtime.CompilerServices.CallerMemberName] string methodName = ".ctor") { - HttpMockServer.Matcher = HpcCacheController.GetRecordMatcher(); + BuildMockServer(); this.mockContext = MockContext.Start(type.Name, methodName); this.RegisterSubscriptionForResource("Microsoft.StorageCache"); } + private void BuildMockServer() + { + var rpToIgnore = new Dictionary + { + { "Microsoft.Resources", null }, + { "Microsoft.Features", null }, + { "Microsoft.Authorization", null }, + { "Microsoft.Network", null }, + }; + var uaToIgnore = new Dictionary + { + { "Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01" }, + { "Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2017-05-10" }, + }; + + HttpMockServer.Matcher = new PermissiveRecordMatcherWithApiExclusion(true, rpToIgnore, uaToIgnore); + HttpMockServer.RecordsDirectory = Path.Combine(GetTestProjectPath(), "SessionRecords"); + } + + private string GetTestProjectPath() + { + var testAssembly = Assembly.GetExecutingAssembly(); + var testProjectPath = testAssembly.GetCustomAttributes().Single(a => a.Key == "TestProjectPath").Value; + + if (string.IsNullOrEmpty(testProjectPath)) + { + throw new InvalidOperationException($"Unable to determine the test directory for {testAssembly}"); + } + + return testProjectPath; + } + /// /// Get service client. /// diff --git a/src/HPCCache/HPCCache.Test/Fixtures/StorageAccountFixture.cs b/src/HPCCache/HPCCache.Test/Fixtures/StorageAccountFixture.cs index 451309f1bf65..7ee775be23c6 100644 --- a/src/HPCCache/HPCCache.Test/Fixtures/StorageAccountFixture.cs +++ b/src/HPCCache/HPCCache.Test/Fixtures/StorageAccountFixture.cs @@ -6,6 +6,7 @@ using System.Web; using Microsoft.Azure.Commands.HPCCache.Test.Helper; using Microsoft.Azure.Commands.HPCCache.Test.Utilities; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.Internal.Resources.Models; using Microsoft.Azure.Management.Storage; using Microsoft.Azure.Management.Storage.Models; diff --git a/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheController.cs b/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheController.cs deleted file mode 100644 index b82ccf7e83cc..000000000000 --- a/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheController.cs +++ /dev/null @@ -1,202 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -namespace Microsoft.Azure.Commands.HPCCache.Test.ScenarioTests -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.IO; - using System.Linq; - using Microsoft.Azure.Commands.Common.Authentication; - using Microsoft.Azure.Commands.HPCCache.Test.Fixtures; - using Microsoft.Azure.Management.Internal.Resources; - using Microsoft.Azure.Management.Storage; - using Microsoft.Azure.Management.StorageCache; - using Microsoft.Azure.ServiceManagement.Common.Models; - using Microsoft.Azure.Test.HttpRecorder; - using Microsoft.WindowsAzure.Commands.ScenarioTest; - using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; - - /// - /// Base test controller class. - /// - public class HpcCacheController : RMTestBase - { - private readonly EnvironmentSetupHelper helper; - - /// - /// Initializes a new instance of the class. - /// - protected HpcCacheController() - { - this.helper = new EnvironmentSetupHelper(); - } - - /// - /// Gets HpcCacheTestBase instance. - /// - public static HpcCacheController NewInstance => new HpcCacheController(); - - /// - /// Gets resource management client. - /// - public ResourceManagementClient ResourceManagementClient { get; private set; } - - /// - /// Gets HPC cache management client. - /// - public StorageCacheManagementClient StorageCacheManagementClient { get; private set; } - - /// - /// Gets storage management client. - /// - public StorageManagementClient StorageManagementClient { get; private set; } - - /// - /// Methods for invoking PowerShell scripts. - /// - /// logger. - /// scripts. - public void RunPsTest(XunitTracingInterceptor logger, params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - logger.Information(string.Format("Test method entered: {0}.{1}", callingClassType, mockName)); - this.RunPsTestWorkflow( - logger, - () => scripts, - null, - callingClassType, - mockName); - logger.Information(string.Format("Test method finished: {0}.{1}", callingClassType, mockName)); - } - - /// - /// Gets storage management client. - /// - static public IRecordMatcher GetRecordMatcher() - { - var d = new Dictionary - { - { "Microsoft.Resources", null }, - { "Microsoft.Features", null }, - { "Microsoft.Authorization", null }, - { "Microsoft.Network", null }, - }; - var providersToIgnore = new Dictionary - { - { "Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01" }, - { "Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2017-05-10" }, - }; - return new PermissiveRecordMatcherWithApiExclusion(true, d, providersToIgnore); - } - - /// - /// RunPsTestWorkflow. - /// - /// logger. - /// scriptBuilder. - /// cleanup. - /// callingClassType. - /// mockName. - /// initialize. - protected void RunPsTestWorkflow( - XunitTracingInterceptor logger, - Func scriptBuilder, - Action cleanup, - string callingClassType, - string mockName, - Action initialize = null) - { - this.helper.TracingInterceptor = logger; - HttpMockServer.Matcher = GetRecordMatcher(); - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (var context = new HpcCacheTestContext(callingClassType, mockName)) - { - initialize?.Invoke(); - this.SetupManagementClients(context); - - var callingClassName = callingClassType.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries).Last(); - this.helper.SetupModules( - AzureModule.AzureResourceManager, - "ScenarioTests\\" + callingClassName + ".ps1", - this.helper.RMProfileModule, - this.helper.GetRMModulePath("Az.HPCCache.psd1"), - "AzureRM.Resources.ps1"); - - try - { - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - this.helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - } - } - } - - /// - /// Management clients. - /// - /// context. - protected void SetupManagementClients(HpcCacheTestContext context) - { - var hpcCacheManagementClient = this.GetHpcCacheManagementClient(context); - var resourceManagementClient = this.GetResourceManagementClient(context); - var storageManagementClient = this.GetStorageManagementClient(context); - - this.helper.SetupManagementClients( - hpcCacheManagementClient, - resourceManagementClient, - storageManagementClient); - } - - /// - /// GetHpcCacheManagementClient. - /// - /// context. - /// StorageCacheManagementClient. - protected StorageCacheManagementClient GetHpcCacheManagementClient(HpcCacheTestContext context) - { - return context.GetClient(); - } - - /// - /// GetResourceManagementClient. - /// - /// context. - /// ResourceManagementClient. - protected ResourceManagementClient GetResourceManagementClient(HpcCacheTestContext context) - { - return context.GetClient(); - } - - /// - /// GetStorageManagementClient. - /// - /// context. - /// StorageManagementClient. - protected StorageManagementClient GetStorageManagementClient(HpcCacheTestContext context) - { - return context.GetClient(); - } - } -} diff --git a/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheTestRunner.cs b/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheTestRunner.cs new file mode 100644 index 000000000000..e26b56cf4baa --- /dev/null +++ b/src/HPCCache/HPCCache.Test/ScenarioTests/HPCCacheTestRunner.cs @@ -0,0 +1,59 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using System.Collections.Generic; +using Xunit.Abstractions; + +namespace Microsoft.Azure.Commands.HPCCache.Test.ScenarioTests +{ + /// + /// Base test controller class. + /// + public class HPCCacheTestRunner + { + protected readonly ITestRunner TestRunner; + + protected HPCCacheTestRunner(ITestOutputHelper output) + { + TestRunner = TestManager.CreateInstance(output) + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithProjectSubfolderForTests("ScenarioTests") + .WithCommonPsScripts(new[] + { + @"../AzureRM.Resources.ps1" + }) + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + helper.GetRMModulePath("Az.HPCCache.psd1") + }) + .WithNewRecordMatcherArguments( + resourceProviders: new Dictionary + { + { "Microsoft.Resources", null }, + { "Microsoft.Features", null }, + { "Microsoft.Authorization", null }, + { "Microsoft.Network", null } + }, + userAgentsToIgnore: new Dictionary + { + { "Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01" }, + { "Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2017-05-10" }, + } + ) + .Build(); + } + } +} diff --git a/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheStorageTargetTest.cs b/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheStorageTargetTest.cs index cb5dbf5b2410..a868275dee60 100644 --- a/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheStorageTargetTest.cs +++ b/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheStorageTargetTest.cs @@ -24,13 +24,8 @@ namespace Microsoft.Azure.Commands.HPCCache.Test.ScenarioTests /// HpcCacheTest. /// [Collection("HpcCacheCollection")] - public class HpcCacheStorageTargetTest : IClassFixture + public class HpcCacheStorageTargetTest : HPCCacheTestRunner, IClassFixture { - /// - /// Defines the testOutputHelper. - /// - private readonly ITestOutputHelper testOutputHelper; - /// /// Defines the Fixture. /// @@ -41,24 +36,16 @@ public class HpcCacheStorageTargetTest : IClassFixture /// private readonly StorageAccountFixture storageAccountFixture; - /// - /// XunitTracingInterceptor. - /// - private readonly XunitTracingInterceptor logger; - /// /// Initializes a new instance of the class. /// /// The testOutputHelper. /// The Fixture. /// Storage account fixture. - public HpcCacheStorageTargetTest(ITestOutputHelper testOutputHelper, HpcCacheTestFixture fixture, StorageAccountFixture storageAccountFixture) + public HpcCacheStorageTargetTest(ITestOutputHelper testOutputHelper, HpcCacheTestFixture fixture, StorageAccountFixture storageAccountFixture) : base(testOutputHelper) { this.fixture = fixture; - this.testOutputHelper = testOutputHelper; this.storageAccountFixture = storageAccountFixture; - this.logger = new XunitTracingInterceptor(this.testOutputHelper); - XunitTracingInterceptor.AddToContext(this.logger); } /// @@ -68,16 +55,7 @@ public HpcCacheStorageTargetTest(ITestOutputHelper testOutputHelper, HpcCacheTes [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetAzHPCCacheStorageTargetByNameAndResourceGroup() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2} {3}", - "Test-GetAzHPCCacheStorageTargetByNameAndResourceGroup", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name, - this.storageAccountFixture.StorageTarget.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-GetAzHPCCacheStorageTargetByNameAndResourceGroup {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name} {this.storageAccountFixture.StorageTarget.Name}"); } /// @@ -87,16 +65,7 @@ public void TestGetAzHPCCacheStorageTargetByNameAndResourceGroup() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetStorgeTarget() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2} {3}", - "Test-SetStorageTarget", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name, - this.storageAccountFixture.StorageTarget.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-SetStorageTarget {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name} {this.storageAccountFixture.StorageTarget.Name}"); } /// @@ -106,16 +75,7 @@ public void TestSetStorgeTarget() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestNewGetSetRemoveST() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2} {3}", - "Test-New-Get-Remove-StorageTarget", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name, - this.fixture.SubscriptionID), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-New-Get-Remove-StorageTarget {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name} {this.fixture.SubscriptionID}"); } } } \ No newline at end of file diff --git a/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheTest.cs b/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheTest.cs index 41f9b3aad5b3..ed00b8ffbd53 100644 --- a/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheTest.cs +++ b/src/HPCCache/HPCCache.Test/ScenarioTests/HpcCacheTest.cs @@ -24,34 +24,21 @@ namespace Microsoft.Azure.Commands.HPCCache.Test.ScenarioTests /// HpcCacheTest. /// [Collection("HpcCacheCollection")] - public class HpcCacheTest + public class HpcCacheTest : HPCCacheTestRunner { - /// - /// Defines the testOutputHelper. - /// - private readonly ITestOutputHelper testOutputHelper; - /// /// Defines the Fixture. /// private readonly HpcCacheTestFixture fixture; - /// - /// XunitTracingInterceptor. - /// - private readonly XunitTracingInterceptor logger; - /// /// Initializes a new instance of the class. /// /// The testOutputHelper. /// The Fixture. - public HpcCacheTest(ITestOutputHelper testOutputHelper, HpcCacheTestFixture fixture) + public HpcCacheTest(ITestOutputHelper testOutputHelper, HpcCacheTestFixture fixture) : base(testOutputHelper) { this.fixture = fixture; - this.testOutputHelper = testOutputHelper; - this.logger = new XunitTracingInterceptor(this.testOutputHelper); - XunitTracingInterceptor.AddToContext(this.logger); } /// @@ -61,15 +48,7 @@ public HpcCacheTest(ITestOutputHelper testOutputHelper, HpcCacheTestFixture fixt [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetCacheByResourceGroupAndName() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2}", - "Test-GetAzHPCCacheByNameAndResourceGroup", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-GetAzHPCCacheByNameAndResourceGroup {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name}"); } /// @@ -79,15 +58,7 @@ public void TestGetCacheByResourceGroupAndName() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestFlushCache() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2}", - "Test-FlushCache", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-FlushCache {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name}"); } /// @@ -97,15 +68,7 @@ public void TestFlushCache() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestStartStopCache() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2}", - "Test-Stop-Start-Cache", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-Stop-Start-Cache {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name}"); } @@ -116,18 +79,7 @@ public void TestStartStopCache() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestNewCacheRemoveCache() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2} {3} {4} {5}", - "Test-NewCache-RemoveCache", - this.fixture.ResourceGroup.Name, - this.fixture.SubscriptionID, - this.fixture.ResourceGroup.Location, - this.fixture.VirtualNetwork.Name, - this.fixture.SubNet.Name) - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-NewCache-RemoveCache {this.fixture.ResourceGroup.Name} {this.fixture.SubscriptionID} {this.fixture.ResourceGroup.Location} {this.fixture.VirtualNetwork.Name} {this.fixture.SubNet.Name}"); } /// @@ -137,15 +89,7 @@ public void TestNewCacheRemoveCache() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetCache() { - var scripts = new string[] - { - string.Format( - "{0} {1} {2}", - "Test-SetCache", - this.fixture.ResourceGroup.Name, - this.fixture.Cache.Name), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-SetCache {this.fixture.ResourceGroup.Name} {this.fixture.Cache.Name}"); } /// @@ -155,13 +99,7 @@ public void TestSetCache() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetUsageModel() { - var scripts = new string[] - { - string.Format( - "{0}", - "Test-GetUsageModel"), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-GetUsageModel"); } /// @@ -171,13 +109,7 @@ public void TestGetUsageModel() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetSku() { - var scripts = new string[] - { - string.Format( - "{0}", - "Test-GetSku"), - }; - HpcCacheController.NewInstance.RunPsTest(this.logger, scripts); + TestRunner.RunTestScript($"Test-GetSku"); } } } \ No newline at end of file diff --git a/src/HPCCache/HPCCache.Test/Utilities/HpcCacheTestEnvironmentUtilities.cs b/src/HPCCache/HPCCache.Test/Utilities/HpcCacheTestEnvironmentUtilities.cs index 50433cccedce..7b4670ad79e2 100644 --- a/src/HPCCache/HPCCache.Test/Utilities/HpcCacheTestEnvironmentUtilities.cs +++ b/src/HPCCache/HPCCache.Test/Utilities/HpcCacheTestEnvironmentUtilities.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.HPCCache.Test.Utilities using System; using System.Collections.Generic; using System.Reflection; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.Rest.ClientRuntime.Azure.TestFramework; diff --git a/src/HPCCache/HPCCache.Test/Utilities/StorageCacheTestUtilities.cs b/src/HPCCache/HPCCache.Test/Utilities/StorageCacheTestUtilities.cs index ad70b840249f..674d89097f39 100644 --- a/src/HPCCache/HPCCache.Test/Utilities/StorageCacheTestUtilities.cs +++ b/src/HPCCache/HPCCache.Test/Utilities/StorageCacheTestUtilities.cs @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Commands.HPCCache.Test.Utilities using System.Collections.Generic; using System.Linq; using System.Text; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.StorageCache.Models; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.Rest.ClientRuntime.Azure.TestFramework; diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/BaseTestController.cs b/src/MachineLearning/MachineLearning.Test/ScenarioTests/BaseTestController.cs deleted file mode 100644 index 98c911903e0c..000000000000 --- a/src/MachineLearning/MachineLearning.Test/ScenarioTests/BaseTestController.cs +++ /dev/null @@ -1,121 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using System; -using System.IO; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Management.Storage.Version2017_10_01; -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.Azure.Management.Internal.Resources; - -namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests -{ - public abstract class BaseTestController where T : ServiceClient - { - private readonly EnvironmentSetupHelper _helper; - private T _serviceClient; - - protected BaseTestController() - { - _helper = new EnvironmentSetupHelper(); - } - - protected abstract T ConstructServiceClient(MockContext context); - - public void RunPsTest(XunitTracingInterceptor logger, params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - _helper.TracingInterceptor = logger; - - RunPsTestWorkflow( - () => scripts, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void RunPsTestWorkflow( - Func scriptBuilder, - Action cleanup, - string callingClassType, - string mockName) - { - var providers = new Dictionary - { - { "Microsoft.Resources", null }, - { "Microsoft.Features", null }, - { "Microsoft.Authorization", null } - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new PermissiveRecordMatcherWithApiExclusion(true, providers, providersToIgnore); - - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - using (var context = MockContext.Start(callingClassType, mockName)) - { - SetupManagementClients(context); - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - var callingClassName = callingClassType.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries).Last(); - - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.RMResourceModule, - _helper.GetRMModulePath(@"AzureRM.MachineLearning.psd1"), - "AzureRM.Storage.ps1", - "AzureRM.Resources.ps1"); - - try - { - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - _helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - } - } - } - - private void SetupManagementClients(MockContext context) - { - _serviceClient = ConstructServiceClient(context); - - var resourceManagementClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - var storageManagementClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - - _helper.SetupManagementClients( - resourceManagementClient, - _serviceClient, - storageManagementClient); - } - } -} diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlanTests.cs b/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlanTests.cs index 9804b1a0d143..6dabf31830ee 100644 --- a/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlanTests.cs +++ b/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlanTests.cs @@ -12,43 +12,38 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; using Xunit; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests { - public class CommitmentPlanTests : RMTestBase + public class CommitmentPlanTests : MachineLearningTestRunner { - private readonly XunitTracingInterceptor interceptor; - - public CommitmentPlanTests(ITestOutputHelper output) + public CommitmentPlanTests(ITestOutputHelper output) : base(output) { - this.interceptor = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(this.interceptor); + } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateGetRemoveCommitmentPlan() { - CommitmentPlansTestController.NewInstance.RunPsTest(this.interceptor, "Test-CreateGetRemoveMLCommitmentPlan"); + TestRunner.RunTestScript("Test-CreateGetRemoveMLCommitmentPlan"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateCommitmentPlan() { - CommitmentPlansTestController.NewInstance.RunPsTest(this.interceptor, "Test-UpdateMLCommitmentPlan"); + TestRunner.RunTestScript("Test-UpdateMLCommitmentPlan"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListCommitmentPlans() { - CommitmentPlansTestController.NewInstance.RunPsTest(this.interceptor, "Test-ListMLCommitmentPlans"); + TestRunner.RunTestScript("Test-ListMLCommitmentPlans"); } } diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/MachineLearningTestRunner.cs b/src/MachineLearning/MachineLearning.Test/ScenarioTests/MachineLearningTestRunner.cs new file mode 100644 index 000000000000..7f9b1264cd56 --- /dev/null +++ b/src/MachineLearning/MachineLearning.Test/ScenarioTests/MachineLearningTestRunner.cs @@ -0,0 +1,58 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using System.Collections.Generic; +using Xunit.Abstractions; + +namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests +{ + public class MachineLearningTestRunner + { + protected readonly ITestRunner TestRunner; + + protected MachineLearningTestRunner(ITestOutputHelper output) + { + TestRunner = TestManager.CreateInstance(output) + .WithNewPsScriptFilename($"{GetType().Name}.ps1") + .WithProjectSubfolderForTests("ScenarioTests") + .WithCommonPsScripts(new[] + { + @"Common.ps1", + @"../AzureRM.Storage.ps1", + @"../AzureRM.Resources.ps1" + }) + .WithNewRmModules(helper => new[] + { + helper.RMProfileModule, + helper.RMResourceModule, + helper.GetRMModulePath("Az.MachineLearning.psd1"), + }) + .WithNewRecordMatcherArguments( + userAgentsToIgnore: new Dictionary + { + {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} + }, + resourceProviders: new Dictionary + { + { "Microsoft.Resources", null }, + { "Microsoft.Features", null }, + { "Microsoft.Authorization", null } + } + ) + .Build(); + } + + } +} diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServiceTests.cs b/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServiceTests.cs index 42bdb0b32dee..488a87c932e7 100644 --- a/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServiceTests.cs +++ b/src/MachineLearning/MachineLearning.Test/ScenarioTests/WebServiceTests.cs @@ -12,57 +12,52 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; using Xunit; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests { - public class WebServiceTests : RMTestBase + public class WebServiceTests : MachineLearningTestRunner { - private readonly XunitTracingInterceptor interceptor; - - public WebServiceTests(ITestOutputHelper output) + public WebServiceTests(ITestOutputHelper output) : base(output) { - this.interceptor = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(this.interceptor); + } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record. MachineLearning tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6684")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateGetRemoveWebService() { - WebServicesTestController.NewInstance.RunPsTest(this.interceptor, "Test-CreateGetRemoveMLService"); + TestRunner.RunTestScript("Test-CreateGetRemoveMLService"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record. MachineLearning tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6684")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateWebServiceFromFile() { - WebServicesTestController.NewInstance.RunPsTest(this.interceptor, "Test-CreateWebServiceFromFile"); + TestRunner.RunTestScript("Test-CreateWebServiceFromFile"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record. MachineLearning tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6684")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateWebService() { - WebServicesTestController.NewInstance.RunPsTest(this.interceptor, "Test-UpdateWebService"); + TestRunner.RunTestScript("Test-UpdateWebService"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record. MachineLearning tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6684")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListWebServices() { - WebServicesTestController.NewInstance.RunPsTest(this.interceptor, "Test-ListWebServices"); + TestRunner.RunTestScript("Test-ListWebServices"); } [Fact(Skip = "Old ResourceManager version in test controller. Update and re-record. MachineLearning tests need to be re-enabled, as outlined in issue https://github.com/Azure/azure-powershell/issues/6684")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateAndGetRegionalProperties() { - WebServicesTestController.NewInstance.RunPsTest(this.interceptor, "Test-CreateAndGetRegionalProperties"); + TestRunner.RunTestScript("Test-CreateAndGetRegionalProperties"); } } } diff --git a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs index 44d6eb230886..6bf8b79569b5 100644 --- a/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs +++ b/src/Network/Network.Test/ScenarioTests/ApplicationGatewayTests.cs @@ -14,8 +14,8 @@ using System; using Microsoft.Azure.Commands.Network.Test.ScenarioTests; +using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; diff --git a/src/Network/Network.Test/ScenarioTests/AzureFirewallPolicyTests.cs b/src/Network/Network.Test/ScenarioTests/AzureFirewallPolicyTests.cs index eaedb2adcd3e..e163aae1f3d0 100644 --- a/src/Network/Network.Test/ScenarioTests/AzureFirewallPolicyTests.cs +++ b/src/Network/Network.Test/ScenarioTests/AzureFirewallPolicyTests.cs @@ -14,8 +14,8 @@ using System; using Microsoft.Azure.Commands.Network.Test.ScenarioTests; +using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Microsoft.WindowsAzure.Commands.ScenarioTest; using Xunit; using Xunit.Abstractions; diff --git a/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs b/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs index c5083607697a..e7a774d668a5 100644 --- a/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs +++ b/src/Network/Network.Test/ScenarioTests/NetworkTestRunner.cs @@ -1,19 +1,25 @@ -using System; -using System.Collections.Generic; +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + using Microsoft.Azure.Commands.TestFx; -using Microsoft.Azure.Internal.Common; using Microsoft.Azure.KeyVault; -using Microsoft.Azure.Management.Compute; -using Microsoft.Azure.Management.Internal.Resources; -using Microsoft.Azure.Management.KeyVault; -using Microsoft.Azure.Management.ManagedServiceIdentity; -using Microsoft.Azure.Management.Network; -using Microsoft.Azure.Management.PrivateDns; -using Microsoft.Azure.Management.Storage; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.IdentityModel.Clients.ActiveDirectory; using Microsoft.Rest; using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using System; +using System.Collections.Generic; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.Network.Test.ScenarioTests @@ -35,15 +41,15 @@ protected NetworkTestRunner(ITestOutputHelper output) .WithNewRmModules (helper => new[] { helper.RMProfileModule, - helper.GetRMModulePath("AzureRM.Monitor.psd1"), - helper.GetRMModulePath("AzureRM.Network.psd1"), - helper.GetRMModulePath("AzureRM.Compute.psd1"), - helper.GetRMModulePath("AzureRM.Storage.psd1"), - helper.GetRMModulePath("AzureRM.Sql.psd1"), - helper.GetRMModulePath("AzureRM.OperationalInsights.psd1"), - helper.GetRMModulePath("AzureRM.KeyVault.psd1"), - helper.GetRMModulePath("AzureRM.ManagedServiceIdentity.psd1"), - helper.GetRMModulePath("AzureRM.PrivateDns.psd1"), + helper.GetRMModulePath("Az.Monitor.psd1"), + helper.GetRMModulePath("Az.Network.psd1"), + helper.GetRMModulePath("Az.Compute.psd1"), + helper.GetRMModulePath("Az.Storage.psd1"), + helper.GetRMModulePath("Az.Sql.psd1"), + helper.GetRMModulePath("Az.OperationalInsights.psd1"), + helper.GetRMModulePath("Az.KeyVault.psd1"), + helper.GetRMModulePath("Az.ManagedServiceIdentity.psd1"), + helper.GetRMModulePath("Az.PrivateDns.psd1"), }) .WithNewRecordMatcherArguments ( userAgentsToIgnore: new Dictionary @@ -64,59 +70,11 @@ protected NetworkTestRunner(ITestOutputHelper output) {"Microsoft.PrivateDns", null}, } ).WithManagementClients( - GetResourceManagementClient, - GetManagedServiceIdentityClient, - GetKeyVaultManagementClient, - GetNetworkManagementClient, - GetComputeManagementClient, - GetStorageManagementClient, - GetKeyVaultClient, - GetAzureRestClient, - GetPrivateDnsManagementClient + GetKeyVaultClient ) .Build(); } - private static ResourceManagementClient GetResourceManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static ManagedServiceIdentityClient GetManagedServiceIdentityClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static KeyVaultManagementClient GetKeyVaultManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static NetworkManagementClient GetNetworkManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static ComputeManagementClient GetComputeManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static StorageManagementClient GetStorageManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static AzureRestClient GetAzureRestClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static PrivateDnsManagementClient GetPrivateDnsManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - private static KeyVaultClient GetKeyVaultClient(MockContext context) { string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); @@ -132,7 +90,7 @@ private static KeyVaultClient GetKeyVaultClient(MockContext context) { string servicePrincipal = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalKey); string servicePrincipalSecret = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalSecretKey); - string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.AADTenantKey); + string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.TenantIdKey); // Create credentials var clientCredentials = new ClientCredential(servicePrincipal, servicePrincipalSecret); diff --git a/src/PowerBIEmbedded/PowerBI.Test/ScenarioTests/UrlDecodingRecordMatcher.cs b/src/PowerBIEmbedded/PowerBI.Test/ScenarioTests/UrlDecodingRecordMatcher.cs index 344db3923050..c8f94608b7e4 100644 --- a/src/PowerBIEmbedded/PowerBI.Test/ScenarioTests/UrlDecodingRecordMatcher.cs +++ b/src/PowerBIEmbedded/PowerBI.Test/ScenarioTests/UrlDecodingRecordMatcher.cs @@ -18,6 +18,7 @@ using System.Linq; using System.Net.Http; using System.Text; +using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.WindowsAzure.Commands.ScenarioTest; namespace Microsoft.Azure.Commands.DataLake.Test.ScenarioTests diff --git a/src/RecoveryServices/RecoveryServices.Backup.Helpers/TrackingHelpers.cs b/src/RecoveryServices/RecoveryServices.Backup.Helpers/TrackingHelpers.cs index 0da594828828..cbc111a1858e 100644 --- a/src/RecoveryServices/RecoveryServices.Backup.Helpers/TrackingHelpers.cs +++ b/src/RecoveryServices/RecoveryServices.Backup.Helpers/TrackingHelpers.cs @@ -142,7 +142,7 @@ public static RestAzureNS.AzureOperationResponse GetOperationResult( public static RestAzureNS.AzureOperationResponse GetOperationStatusDataMove( RestAzureNS.AzureOperationResponse response, Func> getOpStatus) - where T: ServiceClientModel.OperationStatus + where T : ServiceClientModel.OperationStatus { var operationId = response.Response.Headers.GetOperationResultId(); var opStatusResponse = getOpStatus(operationId); @@ -161,7 +161,7 @@ public static RestAzureNS.AzureOperationResponse GetOperationStatusDataMove GetOperationStatusDataMove GetOperationResult( RestAzureNS.AzureOperationResponse response, Func> getOpStatus) - where T: ServiceClientModel.ProtectionContainerResource + where T : ServiceClientModel.ProtectionContainerResource { var operationId = response.Response.Headers.GetOperationResultId(); var opStatusResponse = getOpStatus(operationId); @@ -205,9 +205,9 @@ public static RestAzureNS.AzureOperationResponse GetOperationResult( /// Result of the operation once it completes. public static PrepareDataMoveResponse GetCorrelationId( RestAzureNS.AzureOperationResponse response, - Func getCorrelationId) + Func getCorrelationId) { - var operationId = response.Response.Headers.GetAzureAsyncOperationId(); + var operationId = response.Response.Headers.GetAzureAsyncOperationId(); var opStatusResponse = getCorrelationId(operationId); return opStatusResponse; } @@ -222,12 +222,12 @@ public static PrepareDataMoveResponse GetCorrelationId( public static RestAzureNS.AzureOperationResponse GetOperationResult( RestAzureNS.AzureOperationResponse response, Func> getOpStatus) - where T: ServiceClientModel.ProtectionContainerResource + where T : ServiceClientModel.ProtectionContainerResource { var operationId = response.Response.Headers.GetOperationResultId(); var opStatusResponse = getOpStatus(operationId); - + string testMode = Environment.GetEnvironmentVariable("AZURE_TEST_MODE"); while (opStatusResponse.Response.StatusCode == SystemNet.HttpStatusCode.Accepted) { @@ -268,4 +268,4 @@ public static SystemNet.HttpWebResponse RetryHttpWebRequest(string url, int retr } } } -} +} \ No newline at end of file diff --git a/src/Resources/Resources.Test/Features/GetAzureProviderFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/GetAzureProviderFeatureCmdletTests.cs index 644fd5073d9b..f5f124176bca 100644 --- a/src/Resources/Resources.Test/Features/GetAzureProviderFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/GetAzureProviderFeatureCmdletTests.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Rest.Azure; diff --git a/src/Resources/Resources.Test/Features/GetAzureProviderPreviewFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/GetAzureProviderPreviewFeatureCmdletTests.cs index 0f7475740fe1..4fefc9565a8a 100644 --- a/src/Resources/Resources.Test/Features/GetAzureProviderPreviewFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/GetAzureProviderPreviewFeatureCmdletTests.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Rest.Azure; diff --git a/src/Resources/Resources.Test/Features/RegisterAzureProviderPreviewFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/RegisterAzureProviderPreviewFeatureCmdletTests.cs index e9135d5a64fe..e2daa37efbde 100644 --- a/src/Resources/Resources.Test/Features/RegisterAzureProviderPreviewFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/RegisterAzureProviderPreviewFeatureCmdletTests.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Rest.Azure; diff --git a/src/Resources/Resources.Test/Features/RegisterProviderFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/RegisterProviderFeatureCmdletTests.cs index 32673aa4a056..58829217ab62 100644 --- a/src/Resources/Resources.Test/Features/RegisterProviderFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/RegisterProviderFeatureCmdletTests.cs @@ -32,6 +32,8 @@ namespace Microsoft.Azure.Commands.Resources.Test using WindowsAzure.Commands.Test.Utilities.Common; using Xunit; using Xunit.Abstractions; + using Microsoft.Azure.Commands.TestFx; + /// /// Tests the Azure Provider Feature cmdlets /// diff --git a/src/Resources/Resources.Test/Features/UnregisterAzureProviderPreviewFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/UnregisterAzureProviderPreviewFeatureCmdletTests.cs index d8c4275ab821..93c1f3a2c8cb 100644 --- a/src/Resources/Resources.Test/Features/UnregisterAzureProviderPreviewFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/UnregisterAzureProviderPreviewFeatureCmdletTests.cs @@ -16,6 +16,7 @@ namespace Microsoft.Azure.Commands.Resources.Test { using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Rest.Azure; diff --git a/src/Resources/Resources.Test/Features/UnregisterProviderFeatureCmdletTests.cs b/src/Resources/Resources.Test/Features/UnregisterProviderFeatureCmdletTests.cs index bffc4860b7a8..89e864515b97 100644 --- a/src/Resources/Resources.Test/Features/UnregisterProviderFeatureCmdletTests.cs +++ b/src/Resources/Resources.Test/Features/UnregisterProviderFeatureCmdletTests.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Rest.Azure; diff --git a/src/Resources/Resources.Test/Models.ResourceGroups/ResourceClientTests.cs b/src/Resources/Resources.Test/Models.ResourceGroups/ResourceClientTests.cs index 52c1a5d924d4..a24a30f20562 100644 --- a/src/Resources/Resources.Test/Models.ResourceGroups/ResourceClientTests.cs +++ b/src/Resources/Resources.Test/Models.ResourceGroups/ResourceClientTests.cs @@ -27,6 +27,7 @@ using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels.Deployments; using Microsoft.Azure.Commands.Resources.Models; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.Authorization; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; diff --git a/src/Resources/Resources.Test/Providers/GetAzureProviderCmdletTests.cs b/src/Resources/Resources.Test/Providers/GetAzureProviderCmdletTests.cs index 2c5dc4a518f4..1fb2fac5a9e2 100644 --- a/src/Resources/Resources.Test/Providers/GetAzureProviderCmdletTests.cs +++ b/src/Resources/Resources.Test/Providers/GetAzureProviderCmdletTests.cs @@ -17,6 +17,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Azure.ServiceManagement.Common.Models; diff --git a/src/Resources/Resources.Test/Providers/RegisterResourceProviderCmdletTests.cs b/src/Resources/Resources.Test/Providers/RegisterResourceProviderCmdletTests.cs index f818735595b3..11f38619d9dc 100644 --- a/src/Resources/Resources.Test/Providers/RegisterResourceProviderCmdletTests.cs +++ b/src/Resources/Resources.Test/Providers/RegisterResourceProviderCmdletTests.cs @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; using Microsoft.Azure.Commands.Resources.Models; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Azure.ServiceManagement.Common.Models; diff --git a/src/Resources/Resources.Test/Providers/UnregisterResourceProviderCmdletTests.cs b/src/Resources/Resources.Test/Providers/UnregisterResourceProviderCmdletTests.cs index 90ff5f442d74..45b4c1427070 100644 --- a/src/Resources/Resources.Test/Providers/UnregisterResourceProviderCmdletTests.cs +++ b/src/Resources/Resources.Test/Providers/UnregisterResourceProviderCmdletTests.cs @@ -18,6 +18,7 @@ namespace Microsoft.Azure.Commands.Resources.Test using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkModels; using Microsoft.Azure.Commands.Resources.Models; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Azure.ServiceManagement.Common.Models; diff --git a/src/Resources/Resources.Test/ScenarioTests/DeploymentScopeTests.cs b/src/Resources/Resources.Test/ScenarioTests/DeploymentScopeTests.cs index a53e4fe848c4..edf50b04c9ed 100644 --- a/src/Resources/Resources.Test/ScenarioTests/DeploymentScopeTests.cs +++ b/src/Resources/Resources.Test/ScenarioTests/DeploymentScopeTests.cs @@ -19,42 +19,39 @@ namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests { - public class DeploymentScopeTests + public class DeploymentScopeTests : ResourcesTestRunner { - public XunitTracingInterceptor _logger; - - public DeploymentScopeTests(ITestOutputHelper output) + public DeploymentScopeTests(ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact()] [Trait(Category.AcceptanceType, Category.CheckIn)] public void SubscriptionLevelDeploymentEndToEnd() { - ResourcesController.NewInstance.RunPsTest(_logger, "Test-DeploymentEndToEnd-SubscriptionScope"); + TestRunner.RunTestScript("Test-DeploymentEndToEnd-SubscriptionScope"); } [Fact()] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ResourceGroupDeploymentEndToEnd() { - ResourcesController.NewInstance.RunPsTest(_logger, "Test-DeploymentEndToEnd-ResourceGroup"); + TestRunner.RunTestScript("Test-DeploymentEndToEnd-ResourceGroup"); } [Fact(Skip = "Need to update test Resources")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ManagementGroupLevelDeploymentEndToEnd() { - ResourcesController.NewInstance.RunPsTest(_logger, "Test-DeploymentEndToEnd-ManagementGroup"); + TestRunner.RunTestScript("Test-DeploymentEndToEnd-ManagementGroup"); } [Fact(Skip = "Need to update test Resources")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TenantLevelDeploymentEndToEnd() { - ResourcesController.NewInstance.RunPsTest(_logger, "Test-DeploymentEndToEnd-TenantScope"); + TestRunner.RunTestScript("Test-DeploymentEndToEnd-TenantScope"); } } } diff --git a/src/Resources/Resources.Test/ScenarioTests/PolicyAliasTests.cs b/src/Resources/Resources.Test/ScenarioTests/PolicyAliasTests.cs index bc566314ee41..b92db451ffc4 100644 --- a/src/Resources/Resources.Test/ScenarioTests/PolicyAliasTests.cs +++ b/src/Resources/Resources.Test/ScenarioTests/PolicyAliasTests.cs @@ -24,6 +24,7 @@ namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.SdkClient; using Microsoft.Azure.Commands.ResourceManager.Common; + using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Management.ResourceManager; using Microsoft.Azure.Management.ResourceManager.Models; using Microsoft.Azure.ServiceManagement.Common.Models; diff --git a/src/Resources/Resources.Test/ScenarioTests/ResourcesController.cs b/src/Resources/Resources.Test/ScenarioTests/ResourcesController.cs deleted file mode 100644 index fc22c6add9f7..000000000000 --- a/src/Resources/Resources.Test/ScenarioTests/ResourcesController.cs +++ /dev/null @@ -1,309 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.MSGraph.Version1_0; -using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components; -using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions; -using Microsoft.Azure.Management.Authorization; -using Microsoft.Azure.Management.ManagementGroups; -using Microsoft.Azure.Management.ResourceManager; -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.Rest; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; - -using TestEnvironmentFactory = Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestEnvironmentFactory; - -namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests -{ - public sealed class ResourcesController - { - private readonly EnvironmentSetupHelper _helper; - private const string TenantIdKey = "TenantId"; - private const string DomainKey = "Domain"; - private const string SubscriptionIdKey = "SubscriptionId"; - - public MicrosoftGraphClient GraphClient { get; private set; } - - public ResourceManagementClient ResourceManagementClient { get; private set; } - - public DeploymentScriptsClient DeploymentScriptsClient { get; private set; } - - public FeatureClient FeatureClient { get; private set; } - - public Management.ResourceManager.Version2021_01_01.SubscriptionClient SubscriptionClient { get; private set; } - - public AuthorizationManagementClient AuthorizationManagementClient { get; private set; } - - public ManagementGroupsAPIClient ManagementGroupsApiClient { get; private set; } - - public string UserDomain { get; private set; } - - public static ResourcesController NewInstance => new ResourcesController(); - - public ResourcesController() - { - _helper = new EnvironmentSetupHelper(); - } - - public void RunPsTest(XunitTracingInterceptor interceptor, params string[] scripts) - { - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - RunPsTestWorkflow( - interceptor, - () => scripts, - // no custom cleanup - null, - callingClassType, - mockName); - } - - public void RunPsTestWorkflow( - XunitTracingInterceptor interceptor, - Func scriptBuilder, - Action cleanup, - string callingClassType, - string mockName) - { - _helper.TracingInterceptor = interceptor; - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null}, - {"Providers.Test", null} - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2016-07-01"}, - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new ResourcesRecordMatcher(true, d, providersToIgnore); - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - - using (var context = MockContext.Start(callingClassType, mockName)) - { - _helper.SetupEnvironment(AzureModule.AzureResourceManager); - - SetupManagementClients(context); - - var callingClassName = callingClassType - .Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries) - .Last(); - _helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + callingClassName + ".ps1", - _helper.RMProfileModule, - _helper.RMResourceModule, - _helper.GetRMModulePath("AzureRM.Monitor.psd1")); - - try - { - var psScripts = scriptBuilder?.Invoke(); - if (psScripts != null) - { - _helper.RunPowerShellTest(psScripts); - } - } - finally - { - cleanup?.Invoke(); - } - } - } - - private void SetupManagementClients(MockContext context) - { - ResourceManagementClient = GetResourceManagementClient(context); - SubscriptionClient = GetSubscriptionClient(context); - AuthorizationManagementClient = GetAuthorizationManagementClient(context); - GraphClient = GetGraphClient(context); - ManagementGroupsApiClient = GetManagementGroupsApiClient(context); - FeatureClient = GetFeatureClient(context); - DeploymentScriptsClient = GetDeploymentScriptsClient(context); - var testEnvironment = TestEnvironmentFactory.GetTestEnvironment(); - var credentials = testEnvironment.TokenInfo[TokenAudience.Management]; - HttpClientHelperFactory.Instance = new TestHttpClientHelperFactory(credentials); - - _helper.SetupManagementClients(ResourceManagementClient, - SubscriptionClient, - AuthorizationManagementClient, - GraphClient, - FeatureClient, - ManagementGroupsApiClient, - DeploymentScriptsClient); - } - - private MicrosoftGraphClient GetGraphClient(MockContext context) - { - var environment = TestEnvironmentFactory.GetTestEnvironment(); - string tenantId = null; - - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - tenantId = environment.Tenant; - UserDomain = String.IsNullOrEmpty(environment.UserName) ? String.Empty : environment.UserName.Split(new[] { "@" }, StringSplitOptions.RemoveEmptyEntries).Last(); - - HttpMockServer.Variables[TenantIdKey] = tenantId; - HttpMockServer.Variables[DomainKey] = UserDomain; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - if (HttpMockServer.Variables.ContainsKey(TenantIdKey)) - { - tenantId = HttpMockServer.Variables[TenantIdKey]; - } - if (HttpMockServer.Variables.ContainsKey(DomainKey)) - { - UserDomain = HttpMockServer.Variables[DomainKey]; - } - if (HttpMockServer.Variables.ContainsKey(SubscriptionIdKey)) - { - AzureRmProfileProvider.Instance.Profile.DefaultContext.Subscription.Id = HttpMockServer.Variables[SubscriptionIdKey]; - } - } - - var client = context.GetGraphServiceClient(environment); - client.TenantID = tenantId; - if (AzureRmProfileProvider.Instance != null && - AzureRmProfileProvider.Instance.Profile != null && - AzureRmProfileProvider.Instance.Profile.DefaultContext != null && - AzureRmProfileProvider.Instance.Profile.DefaultContext.Tenant != null) - { - AzureRmProfileProvider.Instance.Profile.DefaultContext.Tenant.Id = client.TenantID; - } - return client; - } - - private static AuthorizationManagementClient GetAuthorizationManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static FeatureClient GetFeatureClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static ResourceManagementClient GetResourceManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static DeploymentScriptsClient GetDeploymentScriptsClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static Management.ResourceManager.Version2021_01_01.SubscriptionClient GetSubscriptionClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - private static ManagementGroupsAPIClient GetManagementGroupsApiClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - /// - /// The test http client helper factory. - /// - private class TestHttpClientHelperFactory : HttpClientHelperFactory - { - /// - /// The service client credentials. - /// - private readonly ServiceClientCredentials _credential; - - /// - /// Initializes a new instance of the class. - /// - /// - public TestHttpClientHelperFactory(ServiceClientCredentials credentials) - { - _credential = credentials; - } - - /// - /// Creates new instances of the class. - /// - /// The credentials. - /// The headers. - public override HttpClientHelper CreateHttpClientHelper(ServiceClientCredentials credentials, IEnumerable headerValues, Dictionary cmdletHeaderValues) - { - return new HttpClientHelperImpl(credentials: _credential, headerValues: headerValues, cmdletHeaderValues: cmdletHeaderValues); - } - - /// - /// An implementation of the abstract class. - /// - private class HttpClientHelperImpl : HttpClientHelper - { - /// - /// Initializes new instances of the class. - /// - /// The credentials. - /// The headers. - public HttpClientHelperImpl(ServiceClientCredentials credentials, IEnumerable headerValues, Dictionary cmdletHeaderValues) - : base(credentials: credentials, headerValues: headerValues, cmdletHeaderValues: cmdletHeaderValues) - { - } - - /// - /// Creates an - /// - /// The handlers that will be added to the top of the chain. - public override HttpClient CreateHttpClient(params DelegatingHandler[] primaryHandlers) - { - return base.CreateHttpClient(HttpMockServer.CreateInstance().AsArray().Concat(primaryHandlers).ToArray()); - } - } - } - - //https://gist.github.com/markcowl/4d907da7ce40f2e424e8d0625887b82e - public class SubscriptionCloudCredentialsAdapter : SubscriptionCloudCredentials - { - private readonly ServiceClientCredentials _wrappedCreds; - - public SubscriptionCloudCredentialsAdapter(ServiceClientCredentials credentials, string subscriptionId) - { - _wrappedCreds = credentials; - SubscriptionId = subscriptionId; - } - - public override string SubscriptionId { get; } - - public override Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken) - { - return _wrappedCreds.ProcessHttpRequestAsync(request, cancellationToken); - } - } - } -} diff --git a/src/Resources/Resources.Test/ScenarioTests/ResourcesRecordMatcher.cs b/src/Resources/Resources.Test/ScenarioTests/ResourcesRecordMatcher.cs index 13b43aa841ac..9eb2cf43b95d 100644 --- a/src/Resources/Resources.Test/ScenarioTests/ResourcesRecordMatcher.cs +++ b/src/Resources/Resources.Test/ScenarioTests/ResourcesRecordMatcher.cs @@ -1,6 +1,19 @@ -using System.Collections.Generic; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.WindowsAzure.Commands.ScenarioTest; +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// -------------------------------------------------------------------------------- + +using System.Collections.Generic; +using Microsoft.Azure.Commands.TestFx.Recorder; namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests { diff --git a/src/Resources/Resources.Test/ScenarioTests/ResourcesTestRunner.cs b/src/Resources/Resources.Test/ScenarioTests/ResourcesTestRunner.cs index f669637587b8..23905942859e 100644 --- a/src/Resources/Resources.Test/ScenarioTests/ResourcesTestRunner.cs +++ b/src/Resources/Resources.Test/ScenarioTests/ResourcesTestRunner.cs @@ -12,17 +12,16 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Components; using Microsoft.Azure.Commands.ResourceManager.Cmdlets.Extensions; using Microsoft.Azure.Commands.TestFx; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.Rest; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests @@ -43,17 +42,20 @@ protected ResourcesTestRunner(ITestOutputHelper output) .WithExtraRmModules(helper => new[] { helper.RMResourceModule, - helper.GetRMModulePath("AzureRM.Monitor.psd1"), - helper.GetRMModulePath(@"Az.ManagedServiceIdentity.psd1"), + helper.GetRMModulePath("Az.Monitor.psd1"), + helper.GetRMModulePath("Az.ManagedServiceIdentity.psd1") }) .WithRecordMatcher( - (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => - new ResourcesRecordMatcher(ignoreResourcesClient, resourceProviders, userAgentsToIgnore)) - .WithExtraUserAgentsToIgnore(new Dictionary - { - {"Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2019-10-01"}, - }) - .WithMockContextAction(() => + (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => new ResourcesRecordMatcher(ignoreResourcesClient, resourceProviders, userAgentsToIgnore) + ) + .WithNewRecordMatcherArguments( + userAgentsToIgnore: new Dictionary + { + { "Microsoft.Azure.Management.ResourceManager.ResourceManagementClient", "2019-10-01" } + }, + resourceProviders: new Dictionary() + ) + .WithMockContextAction(mockContext => { var credentials = HttpMockServer.Mode != HttpRecorderMode.Playback ? new Func(() => diff --git a/src/Resources/Resources.Test/ScenarioTests/RoleAssignmentTests.cs b/src/Resources/Resources.Test/ScenarioTests/RoleAssignmentTests.cs index 5ebb1add7208..0f0c64858703 100644 --- a/src/Resources/Resources.Test/ScenarioTests/RoleAssignmentTests.cs +++ b/src/Resources/Resources.Test/ScenarioTests/RoleAssignmentTests.cs @@ -23,12 +23,9 @@ namespace Microsoft.Azure.Commands.Resources.Test.ScenarioTests { public class RoleAssignmentTests : ResourcesTestRunner { - public XunitTracingInterceptor _logger; - public RoleAssignmentTests(ITestOutputHelper output) : base(output) { - _logger = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(_logger); + } [Fact] @@ -42,7 +39,7 @@ public void RaClassicAdmins() [Trait(Category.AcceptanceType, Category.LiveOnly)] public void RaClassicAdminsWithScope() { - ResourcesController.NewInstance.RunPsTest(_logger, "Test-RaClassicAdminsWithScope"); + TestRunner.RunTestScript("Test-RaClassicAdminsWithScope"); } [Fact] diff --git a/src/Sql/Sql.Test/ScenarioTests/AdvancedDataSecurityManagedInstanceTests.cs b/src/Sql/Sql.Test/ScenarioTests/AdvancedDataSecurityManagedInstanceTests.cs index b53ff1d6e918..a9815f7092fc 100644 --- a/src/Sql/Sql.Test/ScenarioTests/AdvancedDataSecurityManagedInstanceTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/AdvancedDataSecurityManagedInstanceTests.cs @@ -21,29 +21,18 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class AdvancedDataSecurityManagedInstanceTests : SqlTestsBase + public class AdvancedDataSecurityManagedInstanceTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var resourcesClient = GetResourcesClient(context); - var networkClient = GetNetworkClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, networkClient, resourcesClient); - } - public AdvancedDataSecurityManagedInstanceTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances", - "Microsoft.Sql/managedInstances/databases" - }; + } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void AdvancedDataSecurityPolicyTest() { - RunPowerShellTest("Test-AdvancedDataSecurityPolicyManagedInstanceTest"); + TestRunner.RunTestScript("Test-AdvancedDataSecurityPolicyManagedInstanceTest"); } } } \ No newline at end of file diff --git a/src/Sql/Sql.Test/ScenarioTests/AdvisorTests.cs b/src/Sql/Sql.Test/ScenarioTests/AdvisorTests.cs index 4d5eb18e01cf..1ffcc0cf724d 100644 --- a/src/Sql/Sql.Test/ScenarioTests/AdvisorTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/AdvisorTests.cs @@ -19,14 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class AdvisorTests : SqlTestsBase + public class AdvisorTests : SqlTestRunner { public AdvisorTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers", - "Microsoft.Sql/servers/databases" - }; + } #region Server Advisor Tests @@ -35,28 +32,28 @@ public AdvisorTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListServerAdvisors() { - RunPowerShellTest("Test-ListServerAdvisors"); + TestRunner.RunTestScript("Test-ListServerAdvisors"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListServerAdvisorsExpanded() { - RunPowerShellTest("Test-ListServerAdvisorsExpanded"); + TestRunner.RunTestScript("Test-ListServerAdvisorsExpanded"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetServerAdvisor() { - RunPowerShellTest("Test-GetServerAdvisor"); + TestRunner.RunTestScript("Test-GetServerAdvisor"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateServerAdvisor() { - RunPowerShellTest("Test-UpdateServerAdvisor"); + TestRunner.RunTestScript("Test-UpdateServerAdvisor"); } #endregion @@ -67,27 +64,27 @@ public void TestUpdateServerAdvisor() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListDatabaseAdvisors() { - RunPowerShellTest("Test-ListDatabaseAdvisors"); + TestRunner.RunTestScript("Test-ListDatabaseAdvisors"); } [Fact(Skip = "unable to re-record")] public void TestListDatabaseAdvisorsExpanded() { - RunPowerShellTest("Test-ListDatabaseAdvisorsExpanded"); + TestRunner.RunTestScript("Test-ListDatabaseAdvisorsExpanded"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetDatabaseAdvisor() { - RunPowerShellTest("Test-GetDatabaseAdvisor"); + TestRunner.RunTestScript("Test-GetDatabaseAdvisor"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateDatabaseAdvisor() { - RunPowerShellTest("Test-UpdateDatabaseAdvisor"); + TestRunner.RunTestScript("Test-UpdateDatabaseAdvisor"); } #endregion @@ -98,21 +95,21 @@ public void TestUpdateDatabaseAdvisor() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListElasticPoolAdvisors() { - RunPowerShellTest("Test-ListElasticPoolAdvisors"); + TestRunner.RunTestScript("Test-ListElasticPoolAdvisors"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListElasticPoolAdvisorsExpanded() { - RunPowerShellTest("Test-ListElasticPoolAdvisorsExpanded"); + TestRunner.RunTestScript("Test-ListElasticPoolAdvisorsExpanded"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetElasticPoolAdvisor() { - RunPowerShellTest("Test-GetElasticPoolAdvisor"); + TestRunner.RunTestScript("Test-GetElasticPoolAdvisor"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/Common.ps1 b/src/Sql/Sql.Test/ScenarioTests/Common.ps1 index 3035de38386d..742b7482a577 100644 --- a/src/Sql/Sql.Test/ScenarioTests/Common.ps1 +++ b/src/Sql/Sql.Test/ScenarioTests/Common.ps1 @@ -942,7 +942,7 @@ function Get-DNSNameBasedOnEnvironment () { $connectingString = [System.Environment]::GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION") $parsedString = [Microsoft.Rest.ClientRuntime.Azure.TestFramework.TestUtilities]::ParseConnectionString($connectingString) - $environment = $parsedString[[Microsoft.Rest.ClientRuntime.Azure.TestFramework.ConnectionStringKeys]::EnvironmentKey] + $environment = $parsedString[[Microsoft.Azure.Commands.TestFx.ConnectionStringKeys]::EnvironmentKey] if ($environment -eq "Dogfood"){ return ".sqltest-eg1.mscds.com" } diff --git a/src/Sql/Sql.Test/ScenarioTests/DataClassificationTests.cs b/src/Sql/Sql.Test/ScenarioTests/DataClassificationTests.cs index be925826b166..e7e74826e505 100644 --- a/src/Sql/Sql.Test/ScenarioTests/DataClassificationTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/DataClassificationTests.cs @@ -19,50 +19,39 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class DataClassificationTests : SqlTestsBase + public class DataClassificationTests : SqlTestRunner { public DataClassificationTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances", - "Microsoft.Sql/servers", - "Microsoft.Sql/managedInstances/databases" - }; - } - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var networkClient = GetNetworkClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient); } + [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDataClassificationOnSqlDatabase() { - RunPowerShellTest("Test-DataClassificationOnSqlDatabase"); + TestRunner.RunTestScript("Test-DataClassificationOnSqlDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestErrorIsThrownWhenInvalidClassificationIsSet() { - RunPowerShellTest("Test-ErrorIsThrownWhenInvalidClassificationIsSet"); + TestRunner.RunTestScript("Test-ErrorIsThrownWhenInvalidClassificationIsSet"); } [Fact(Skip = "not able to re - record because 'Managed Instance is not accepting creation of instances with General Purpose edition and Generation 4 hardware in this region.'")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestBasicDataClassificationOnSqlManagedDatabase() { - RunPowerShellTest("Test-BasicDataClassificationOnSqlManagedDatabase"); + TestRunner.RunTestScript("Test-BasicDataClassificationOnSqlManagedDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestEnableDisableRecommendationsOnSqlDatabase() { - RunPowerShellTest("Test-EnableDisableRecommendationsOnSqlDatabase"); + TestRunner.RunTestScript("Test-EnableDisableRecommendationsOnSqlDatabase"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/DataMaskingTests.cs b/src/Sql/Sql.Test/ScenarioTests/DataMaskingTests.cs index cd2b4d515859..5c7a3a8e1309 100644 --- a/src/Sql/Sql.Test/ScenarioTests/DataMaskingTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/DataMaskingTests.cs @@ -20,15 +20,8 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class DataMaskingTests : SqlTestsBase + public class DataMaskingTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient); - } - public DataMaskingTests(ITestOutputHelper output) : base(output) { base.resourceTypesToIgnoreApiVersion = new string[] { @@ -40,42 +33,42 @@ public DataMaskingTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingPrivilegedUsersChanges() { - RunPowerShellTest("Test-DatabaseDataMaskingPrivilegedUsersChanges"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingPrivilegedUsersChanges"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingBasicRuleLifecycle() { - RunPowerShellTest("Test-DatabaseDataMaskingBasicRuleLifecycle"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingBasicRuleLifecycle"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingNumberRuleLifecycle() { - RunPowerShellTest("Test-DatabaseDataMaskingNumberRuleLifecycle"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingNumberRuleLifecycle"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingTextRuleLifecycle() { - RunPowerShellTest("Test-DatabaseDataMaskingTextRuleLifecycle"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingTextRuleLifecycle"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingRuleCreationFailures() { - RunPowerShellTest("Test-DatabaseDataMaskingRuleCreationFailures"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingRuleCreationFailures"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabaseDataMaskingRuleCreationWithoutPolicy() { - RunPowerShellTest("Test-DatabaseDataMaskingRuleCreationWithoutPolicy"); + TestRunner.RunTestScript("Test-DatabaseDataMaskingRuleCreationWithoutPolicy"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/DataSyncTests.cs b/src/Sql/Sql.Test/ScenarioTests/DataSyncTests.cs index bccee04301d8..e15301f215b4 100644 --- a/src/Sql/Sql.Test/ScenarioTests/DataSyncTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/DataSyncTests.cs @@ -20,121 +20,116 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class DataSyncTests : SqlTestsBase + public class DataSyncTests : SqlTestRunner { public DataSyncTests(ITestOutputHelper output) : base(output) { - XunitTracingInterceptor.AddToContext(new XunitTracingInterceptor(output)); - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers", - "Microsoft.Sql/managedInstances/databases" - }; } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncAgentCreate() { - RunPowerShellTest("Test-CreateSyncAgent"); + TestRunner.RunTestScript("Test-CreateSyncAgent"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncAgentsGetAndList() { - RunPowerShellTest("Test-GetAndListSyncAgents"); + TestRunner.RunTestScript("Test-GetAndListSyncAgents"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncAgentRemove() { - RunPowerShellTest("Test-RemoveSyncAgent"); + TestRunner.RunTestScript("Test-RemoveSyncAgent"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncAgentKeyCreate() { - RunPowerShellTest("Test-CreateSyncAgentKey"); + TestRunner.RunTestScript("Test-CreateSyncAgentKey"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncAgentLinkedDatabaseList() { - RunPowerShellTest("Test-listSyncAgentLinkedDatabase"); + TestRunner.RunTestScript("Test-listSyncAgentLinkedDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncGroupCreate() { - RunPowerShellTest("Test-CreateSyncGroup"); + TestRunner.RunTestScript("Test-CreateSyncGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncGroupUpdate() { - RunPowerShellTest("Test-UpdateSyncGroup"); + TestRunner.RunTestScript("Test-UpdateSyncGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncGroupsGetAndList() { - RunPowerShellTest("Test-GetAndListSyncGroups"); + TestRunner.RunTestScript("Test-GetAndListSyncGroups"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncGroupHubSchemaRefreshAndGet() { - RunPowerShellTest("Test-RefreshAndGetSyncGroupHubSchema"); + TestRunner.RunTestScript("Test-RefreshAndGetSyncGroupHubSchema"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncGroupRemove() { - RunPowerShellTest("Test-RemoveSyncGroup"); + TestRunner.RunTestScript("Test-RemoveSyncGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncMemberCreate() { - RunPowerShellTest("Test-CreateSyncMember"); + TestRunner.RunTestScript("Test-CreateSyncMember"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncMembersGetAndList() { - RunPowerShellTest("Test-GetAndListSyncMembers"); + TestRunner.RunTestScript("Test-GetAndListSyncMembers"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncMemberUpdate() { - RunPowerShellTest("Test-UpdateSyncMember"); + TestRunner.RunTestScript("Test-UpdateSyncMember"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncMemberSchemaRefreshAndGet() { - RunPowerShellTest("Test-RefreshAndGetSyncMemberSchema"); + TestRunner.RunTestScript("Test-RefreshAndGetSyncMemberSchema"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSyncMemberRemove() { - RunPowerShellTest("Test-RemoveSyncMember"); + TestRunner.RunTestScript("Test-RemoveSyncMember"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/DatabaseActivationTests.cs b/src/Sql/Sql.Test/ScenarioTests/DatabaseActivationTests.cs index 9158d53e5579..ac830e171778 100644 --- a/src/Sql/Sql.Test/ScenarioTests/DatabaseActivationTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/DatabaseActivationTests.cs @@ -19,27 +19,25 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class DatabaseActivationTests : SqlTestsBase + public class DatabaseActivationTests : SqlTestRunner { public DatabaseActivationTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact(Skip = "The test takes the longest time to run. Skip it to workaround timeout temporarily.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabasePauseResume() { - RunPowerShellTest("Test-DatabasePauseResume"); + TestRunner.RunTestScript("Test-DatabasePauseResume"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDatabasePauseResumePiped() { - RunPowerShellTest("Test-DatabasePauseResumePiped"); + TestRunner.RunTestScript("Test-DatabasePauseResumePiped"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/DatabaseReplicationTests.cs b/src/Sql/Sql.Test/ScenarioTests/DatabaseReplicationTests.cs index 2ee2c7f09f0a..2b871ce182b6 100644 --- a/src/Sql/Sql.Test/ScenarioTests/DatabaseReplicationTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/DatabaseReplicationTests.cs @@ -19,83 +19,81 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class DatabaseReplicationTests : SqlTestsBase + public class DatabaseReplicationTests : SqlTestRunner { public DatabaseReplicationTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateDatabaseCopy() { - RunPowerShellTest("Test-CreateDatabaseCopy"); + TestRunner.RunTestScript("Test-CreateDatabaseCopy"); } [Fact(Skip = "Taking too long - try again before PR merge")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateVcoreDatabaseCopy() { - RunPowerShellTest("Test-CreateVcoreDatabaseCopy"); + TestRunner.RunTestScript("Test-CreateVcoreDatabaseCopy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateSecondaryDatabase() { - RunPowerShellTest("Test-CreateSecondaryDatabase"); + TestRunner.RunTestScript("Test-CreateSecondaryDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateNamedSecondaryDatabase() { - RunPowerShellTest("Test-CreateNamedSecondaryDatabase"); + TestRunner.RunTestScript("Test-CreateNamedSecondaryDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateNamedSecondaryDatabaseNegative() { - RunPowerShellTest("Test-CreateNamedSecondaryDatabaseNegative"); + TestRunner.RunTestScript("Test-CreateNamedSecondaryDatabaseNegative"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetReplicationLink() { - RunPowerShellTest("Test-GetReplicationLink"); + TestRunner.RunTestScript("Test-GetReplicationLink"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestRemoveSecondaryDatabase() { - RunPowerShellTest("Test-RemoveSecondaryDatabase"); + TestRunner.RunTestScript("Test-RemoveSecondaryDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestFailoverSecondaryDatabase() { - RunPowerShellTest("Test-FailoverSecondaryDatabase"); + TestRunner.RunTestScript("Test-FailoverSecondaryDatabase"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateDatabaseCopyWithBackupStorageRedundancy() { - RunPowerShellTest("Test-CreateDatabaseCopyWithBackupStorageRedundancy"); + TestRunner.RunTestScript("Test-CreateDatabaseCopyWithBackupStorageRedundancy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateSecondaryDatabaseWithBackupStorageRedundancy() { - RunPowerShellTest("Test-CreateSecondaryDatabaseWithBackupStorageRedundancy"); + TestRunner.RunTestScript("Test-CreateSecondaryDatabaseWithBackupStorageRedundancy"); } [Fact] @@ -116,28 +114,28 @@ public void TestCreateSecondaryDatabaseWithGeoZoneBackupStorageRedundancy() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateCopyRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant() { - RunPowerShellTest("Test-CreateCopyRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant"); + TestRunner.RunTestScript("Test-CreateCopyRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant"); } [Fact(Skip = "Location 'East US 2 EUAP' is not accepting creation of new Windows Azure SQL Database servers at this time.'")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateCopyRegularAndZoneRedundantDatabaseWithSourceZoneRedundant() { - RunPowerShellTest("Test-CreateCopyRegularAndZoneRedundantDatabaseWithSourceZoneRedundant"); + TestRunner.RunTestScript("Test-CreateCopyRegularAndZoneRedundantDatabaseWithSourceZoneRedundant"); } [Fact(Skip = "Location 'East US 2 EUAP' is not accepting creation of new Windows Azure SQL Database servers at this time.'")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateSecondaryRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant() { - RunPowerShellTest("Test-CreateSecondaryRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant"); + TestRunner.RunTestScript("Test-CreateSecondaryRegularAndZoneRedundantDatabaseWithSourceNotZoneRedundant"); } [Fact(Skip = "Location 'East US 2 EUAP' is not accepting creation of new Windows Azure SQL Database servers at this time.'")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateSecondaryRegularAndZoneRedundantDatabaseWithSourceZoneRedundant() { - RunPowerShellTest("Test-CreateSecondaryRegularAndZoneRedundantDatabaseWithSourceZoneRedundant"); + TestRunner.RunTestScript("Test-CreateSecondaryRegularAndZoneRedundantDatabaseWithSourceZoneRedundant"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobCredentialCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobCredentialCrudTests.cs index afdaac601543..2d4c39716fd8 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobCredentialCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobCredentialCrudTests.cs @@ -19,13 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobCredentialCrudTests : SqlTestsBase + public class ElasticJobCredentialCrudTests : SqlTestRunner { public ElasticJobCredentialCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } #region Create Tests @@ -34,7 +32,7 @@ public ElasticJobCredentialCrudTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCredentialCreate() { - RunPowerShellTest("Test-CreateJobCredential"); + TestRunner.RunTestScript("Test-CreateJobCredential"); } #endregion @@ -45,7 +43,7 @@ public void TestJobCredentialCreate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCredentialUpdate() { - RunPowerShellTest("Test-UpdateJobCredential"); + TestRunner.RunTestScript("Test-UpdateJobCredential"); } #endregion @@ -56,7 +54,7 @@ public void TestJobCredentialUpdate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCredentialGet() { - RunPowerShellTest("Test-GetJobCredential"); + TestRunner.RunTestScript("Test-GetJobCredential"); } #endregion @@ -67,7 +65,7 @@ public void TestJobCredentialGet() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCredentialRemove() { - RunPowerShellTest("Test-RemoveJobCredential"); + TestRunner.RunTestScript("Test-RemoveJobCredential"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobCrudTests.cs index 52f6dcd17ed9..f01ef6fa69a4 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobCrudTests.cs @@ -19,13 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobCrudTests : SqlTestsBase + public class ElasticJobCrudTests : SqlTestRunner { public ElasticJobCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } #region Create Tests @@ -37,7 +35,7 @@ public ElasticJobCrudTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobCreate() { - RunPowerShellTest("Test-CreateJob"); + TestRunner.RunTestScript("Test-CreateJob"); } #endregion @@ -48,7 +46,7 @@ public void TestJobCreate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobUpdate() { - RunPowerShellTest("Test-UpdateJob"); + TestRunner.RunTestScript("Test-UpdateJob"); } #endregion @@ -59,7 +57,7 @@ public void TestJobUpdate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobGet() { - RunPowerShellTest("Test-GetJob"); + TestRunner.RunTestScript("Test-GetJob"); } #endregion @@ -70,7 +68,7 @@ public void TestJobGet() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobRemove() { - RunPowerShellTest("Test-RemoveJob"); + TestRunner.RunTestScript("Test-RemoveJob"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobExecutionCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobExecutionCrudTests.cs index a8d28130e17e..e438469354d8 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobExecutionCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobExecutionCrudTests.cs @@ -19,13 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobExecutionCrudTests : SqlTestsBase + public class ElasticJobExecutionCrudTests : SqlTestRunner { public ElasticJobExecutionCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } #region Start Job Tests @@ -34,14 +32,14 @@ public ElasticJobExecutionCrudTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStart() { - RunPowerShellTest("Test-StartJob"); + TestRunner.RunTestScript("Test-StartJob"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStartWait() { - RunPowerShellTest("Test-StartJobWait"); + TestRunner.RunTestScript("Test-StartJobWait"); } #endregion @@ -52,7 +50,7 @@ public void TestJobStartWait() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStop() { - RunPowerShellTest("Test-StopJob"); + TestRunner.RunTestScript("Test-StopJob"); } #endregion @@ -63,7 +61,7 @@ public void TestJobStop() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobExecutionGet() { - RunPowerShellTest("Test-GetJobExecution"); + TestRunner.RunTestScript("Test-GetJobExecution"); } #endregion @@ -75,7 +73,7 @@ public void TestJobExecutionGet() public void TestJobStepExecutionGet() { - RunPowerShellTest("Test-GetJobStepExecution"); + TestRunner.RunTestScript("Test-GetJobStepExecution"); } #endregion @@ -86,7 +84,7 @@ public void TestJobStepExecutionGet() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobTargetExecutionGet() { - RunPowerShellTest("Test-GetJobTargetExecution"); + TestRunner.RunTestScript("Test-GetJobTargetExecution"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobStepCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobStepCrudTests.cs index 92a155cc65ca..57b4a33ee558 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobStepCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobStepCrudTests.cs @@ -19,13 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobStepCrudTests : SqlTestsBase + public class ElasticJobStepCrudTests : SqlTestRunner { public ElasticJobStepCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } #region Create Tests @@ -34,7 +32,7 @@ public ElasticJobStepCrudTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStepCreate() { - RunPowerShellTest("Test-CreateJobStep"); + TestRunner.RunTestScript("Test-CreateJobStep"); } #endregion @@ -45,7 +43,7 @@ public void TestJobStepCreate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStepUpdate() { - RunPowerShellTest("Test-UpdateJobStep"); + TestRunner.RunTestScript("Test-UpdateJobStep"); } #endregion @@ -56,7 +54,7 @@ public void TestJobStepUpdate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStepGet() { - RunPowerShellTest("Test-GetJobStep"); + TestRunner.RunTestScript("Test-GetJobStep"); } #endregion @@ -67,7 +65,7 @@ public void TestJobStepGet() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestJobStepRemove() { - RunPowerShellTest("Test-RemoveJobStep"); + TestRunner.RunTestScript("Test-RemoveJobStep"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetCrudTests.cs index 9a6bf43144fa..f28d5c237bca 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetCrudTests.cs @@ -19,27 +19,25 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobTargetCrudTests : SqlTestsBase + public class ElasticJobTargetCrudTests : SqlTestRunner { public ElasticJobTargetCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTargetAdd() { - RunPowerShellTest("Test-AddTarget"); + TestRunner.RunTestScript("Test-AddTarget"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTargetRemove() { - RunPowerShellTest("Test-RemoveTarget"); + TestRunner.RunTestScript("Test-RemoveTarget"); } } } \ No newline at end of file diff --git a/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetGroupCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetGroupCrudTests.cs index d5024729eee6..4e288dd9b197 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetGroupCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ElasticJobTargetGroupCrudTests.cs @@ -19,13 +19,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ElasticJobTargetGroupCrudTests : SqlTestsBase + public class ElasticJobTargetGroupCrudTests : SqlTestRunner { public ElasticJobTargetGroupCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } #region Create Tests @@ -34,7 +32,7 @@ public ElasticJobTargetGroupCrudTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTargetGroupCreate() { - RunPowerShellTest("Test-CreateTargetGroup"); + TestRunner.RunTestScript("Test-CreateTargetGroup"); } #endregion @@ -45,7 +43,7 @@ public void TestTargetGroupCreate() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTargetGroupGet() { - RunPowerShellTest("Test-GetTargetGroup"); + TestRunner.RunTestScript("Test-GetTargetGroup"); } #endregion @@ -56,7 +54,7 @@ public void TestTargetGroupGet() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestTargetGroupRemove() { - RunPowerShellTest("Test-RemoveTargetGroup"); + TestRunner.RunTestScript("Test-RemoveTargetGroup"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/FailoverGroupTests.cs b/src/Sql/Sql.Test/ScenarioTests/FailoverGroupTests.cs index f50e8b1dbf13..1921b07d0af4 100644 --- a/src/Sql/Sql.Test/ScenarioTests/FailoverGroupTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/FailoverGroupTests.cs @@ -19,146 +19,144 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class FailoverGroupTests : SqlTestsBase + public class FailoverGroupTests : SqlTestRunner { public FailoverGroupTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestFailoverGroup() { - RunPowerShellTest("Test-FailoverGroup"); + TestRunner.RunTestScript("Test-FailoverGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_Named() { - RunPowerShellTest("Test-CreateFailoverGroup-Named"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-Named"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_Positional() { - RunPowerShellTest("Test-CreateFailoverGroup-Positional"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-Positional"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_AutomaticPolicy() { - RunPowerShellTest("Test-CreateFailoverGroup-AutomaticPolicy"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-AutomaticPolicy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_AutomaticPolicyGracePeriodReadOnlyFailover() { - RunPowerShellTest("Test-CreateFailoverGroup-AutomaticPolicyGracePeriodReadOnlyFailover"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-AutomaticPolicyGracePeriodReadOnlyFailover"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_ZeroGracePeriod() { - RunPowerShellTest("Test-CreateFailoverGroup-ZeroGracePeriod"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-ZeroGracePeriod"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_ManualPolicy() { - RunPowerShellTest("Test-CreateFailoverGroup-ManualPolicy"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-ManualPolicy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateFailoverGroup_Overflow() { - RunPowerShellTest("Test-CreateFailoverGroup-Overflow"); + TestRunner.RunTestScript("Test-CreateFailoverGroup-Overflow"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_Named() { - RunPowerShellTest("Test-SetFailoverGroup-Named"); + TestRunner.RunTestScript("Test-SetFailoverGroup-Named"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_Positional() { - RunPowerShellTest("Test-SetFailoverGroup-Positional"); + TestRunner.RunTestScript("Test-SetFailoverGroup-Positional"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_PipeServer() { - RunPowerShellTest("Test-SetFailoverGroup-PipeServer"); + TestRunner.RunTestScript("Test-SetFailoverGroup-PipeServer"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_AutomaticWithGracePeriodReadOnlyFailover() { - RunPowerShellTest("Test-SetFailoverGroup-AutomaticWithGracePeriodReadOnlyFailover"); + TestRunner.RunTestScript("Test-SetFailoverGroup-AutomaticWithGracePeriodReadOnlyFailover"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_AutomaticWithGracePeriodZero() { - RunPowerShellTest("Test-SetFailoverGroup-AutomaticWithGracePeriodZero"); + TestRunner.RunTestScript("Test-SetFailoverGroup-AutomaticWithGracePeriodZero"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_AutomaticToManual() { - RunPowerShellTest("Test-SetFailoverGroup-AutomaticToManual"); + TestRunner.RunTestScript("Test-SetFailoverGroup-AutomaticToManual"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_ManualToAutomaticNoGracePeriod() { - RunPowerShellTest("Test-SetFailoverGroup-ManualToAutomaticNoGracePeriod"); + TestRunner.RunTestScript("Test-SetFailoverGroup-ManualToAutomaticNoGracePeriod"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetFailoverGroup_Overflow() { - RunPowerShellTest("Test-SetFailoverGroup-Overflow"); + TestRunner.RunTestScript("Test-SetFailoverGroup-Overflow"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void Test_AddRemoveDatabasesToFromFailoverGroup() { - RunPowerShellTest("Test-AddRemoveDatabasesToFromFailoverGroup"); + TestRunner.RunTestScript("Test-AddRemoveDatabasesToFromFailoverGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSwitchFailoverGroup() { - RunPowerShellTest("Test-SwitchFailoverGroup"); + TestRunner.RunTestScript("Test-SwitchFailoverGroup"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSwitchFailoverGroupAllowDataLoss() { - RunPowerShellTest("Test-SwitchFailoverGroupAllowDataLoss"); + TestRunner.RunTestScript("Test-SwitchFailoverGroupAllowDataLoss"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ImportExportTests.cs b/src/Sql/Sql.Test/ScenarioTests/ImportExportTests.cs index 1630061abfe0..7612c75dacd7 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ImportExportTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ImportExportTests.cs @@ -19,27 +19,25 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ImportExportTests : SqlTestsBase + public class ImportExportTests : SqlTestRunner { public ImportExportTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestExportDatabase() { - RunPowerShellTest("Test-ExportDatabase"); + TestRunner.RunTestScript("Test-ExportDatabase"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestExportDatabase_NetworkIsolation() { - RunPowerShellTest("Test-ExportDatabaseNetworkIsolation"); + TestRunner.RunTestScript("Test-ExportDatabaseNetworkIsolation"); } [Fact(Skip = "Cannot re-record.")] @@ -47,7 +45,7 @@ public void TestExportDatabase_NetworkIsolation() [Trait(Category.Sql, "Needs to be re-recorded")] public void TestImportNewDatabase() { - RunPowerShellTest("Test-ImportNewDatabase"); + TestRunner.RunTestScript("Test-ImportNewDatabase"); } [Fact(Skip = "Cannot re-record.")] @@ -55,7 +53,7 @@ public void TestImportNewDatabase() [Trait(Category.Sql, "Needs to be re-recorded")] public void TestImportNewDatabase_NetworkIsolation() { - RunPowerShellTest("Test-ImportNewDatabaseNetworkIsolation"); + TestRunner.RunTestScript("Test-ImportNewDatabaseNetworkIsolation"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/IndexRecommendationTests.cs b/src/Sql/Sql.Test/ScenarioTests/IndexRecommendationTests.cs index 43b26cea0b79..54c3f41c4fcf 100644 --- a/src/Sql/Sql.Test/ScenarioTests/IndexRecommendationTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/IndexRecommendationTests.cs @@ -20,10 +20,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class IndexRecommendationTests : SqlTestsBase + public class IndexRecommendationTests : SqlTestRunner { public IndexRecommendationTests(ITestOutputHelper output) : base(output) { + } [Fact] @@ -34,7 +35,7 @@ public void TestGetIndexRecommendation() // TODO https://github.com/Azure/azure-powershell/issues/4156 if (TestMockSupport.RunningMocked) { - RunPowerShellTest("Test-GetIndexRecommendations"); + TestRunner.RunTestScript("Test-GetIndexRecommendations"); } } @@ -46,7 +47,7 @@ public void TestCreateIndex() // TODO https://github.com/Azure/azure-powershell/issues/4156 if (TestMockSupport.RunningMocked) { - RunPowerShellTest("Test-CreateIndex"); + TestRunner.RunTestScript("Test-CreateIndex"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/InstancePoolCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/InstancePoolCrudTests.cs index 3444fdbfa96f..c94460eaebd0 100644 --- a/src/Sql/Sql.Test/ScenarioTests/InstancePoolCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/InstancePoolCrudTests.cs @@ -20,20 +20,12 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class InstancePoolCrudTests : SqlTestsBase + public class InstancePoolCrudTests : SqlTestRunner { public InstancePoolCrudTests(ITestOutputHelper output) : base(output) { } - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var networkClient = GetNetworkClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient); - } - #region Instance pool /// @@ -43,7 +35,7 @@ protected override void SetupManagementClients(RestTestFramework.MockContext con [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateInstancePool() { - RunPowerShellTest("Test-CreateInstancePool"); + TestRunner.RunTestScript("Test-CreateInstancePool"); } /// @@ -53,7 +45,7 @@ public void TestCreateInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateInstancePool() { - RunPowerShellTest("Test-UpdateInstancePool"); + TestRunner.RunTestScript("Test-UpdateInstancePool"); } /// @@ -63,14 +55,14 @@ public void TestUpdateInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetInstancePool() { - RunPowerShellTest("Test-GetInstancePool"); + TestRunner.RunTestScript("Test-GetInstancePool"); } [Fact(Skip = "Skip due to long setup time for managed instance pool")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestRemoveInstancePool() { - RunPowerShellTest("Test-RemoveInstancePool"); + TestRunner.RunTestScript("Test-RemoveInstancePool"); } #endregion @@ -84,7 +76,7 @@ public void TestRemoveInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCreateManagedInstanceInInstancePool() { - RunPowerShellTest("Test-CreateManagedInstanceInInstancePool"); + TestRunner.RunTestScript("Test-CreateManagedInstanceInInstancePool"); } /// @@ -94,7 +86,7 @@ public void TestCreateManagedInstanceInInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetManagedInstanceInInstancePool() { - RunPowerShellTest("Test-GetManagedInstanceInInstancePool"); + TestRunner.RunTestScript("Test-GetManagedInstanceInInstancePool"); } /// @@ -104,7 +96,7 @@ public void TestGetManagedInstanceInInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateManagedInstanceInInstancePool() { - RunPowerShellTest("Test-UpdateManagedInstanceInInstancePool"); + TestRunner.RunTestScript("Test-UpdateManagedInstanceInInstancePool"); } /// @@ -114,7 +106,7 @@ public void TestUpdateManagedInstanceInInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestDeleteManagedInstanceInInstancePool() { - RunPowerShellTest("Test-DeleteManagedInstanceInInstancePool"); + TestRunner.RunTestScript("Test-DeleteManagedInstanceInInstancePool"); } #endregion @@ -128,7 +120,7 @@ public void TestDeleteManagedInstanceInInstancePool() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetInstancePoolUsage() { - RunPowerShellTest("Test-GetInstancePoolUsage"); + TestRunner.RunTestScript("Test-GetInstancePoolUsage"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/ManagedDatabaseLogReplayScenarioTest.cs b/src/Sql/Sql.Test/ScenarioTests/ManagedDatabaseLogReplayScenarioTest.cs index d86263c3836c..c1d24fad4bc2 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ManagedDatabaseLogReplayScenarioTest.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ManagedDatabaseLogReplayScenarioTest.cs @@ -20,64 +20,53 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ManagedDatabaseLogReplayScenarioTest : SqlTestsBase + public class ManagedDatabaseLogReplayScenarioTest : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var networkClient = GetNetworkClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient); - } - public ManagedDatabaseLogReplayScenarioTest(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances", - "Microsoft.Sql/managedInstances/databases" - }; + } [Fact(Skip = "Depends on hardcoded resource to rerecord")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedDatabaseLogReplayService() { - RunPowerShellTest("Test-ManagedDatabaseLogReplay"); + TestRunner.RunTestScript("Test-ManagedDatabaseLogReplay"); } [Fact(Skip = "Depends on hardcoded resource to rerecord")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCompleteManagedDatabaseLogReplayService() { - RunPowerShellTest("Test-CompleteManagedDatabaseLogReplay"); + TestRunner.RunTestScript("Test-CompleteManagedDatabaseLogReplay"); } [Fact(Skip = "Depends on hardcoded resource to rerecord")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCancelManagedDatabaseLogReplayService() { - RunPowerShellTest("Test-CancelManagedDatabaseLogReplay"); + TestRunner.RunTestScript("Test-CancelManagedDatabaseLogReplay"); } [Fact(Skip = "Depends on hardcoded resource to rerecord")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestPipingManagedDatabaseLogReplayService() { - RunPowerShellTest("Test-ManagedDatabaseLogReplayPiping"); + TestRunner.RunTestScript("Test-ManagedDatabaseLogReplayPiping"); } [Fact(Skip = "Depends on hardcoded resource to rerecord")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestPipingCompleteCancelManagedDatabaseLogReplayService() { - RunPowerShellTest("Test-PipingCompleteCancelManagedDatabaseLogReplay"); + TestRunner.RunTestScript("Test-PipingCompleteCancelManagedDatabaseLogReplay"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestCancelManagedDatabaseLogReplayFailForWrongDatabase() { - RunPowerShellTest("Test-CancelManagedDatabaseLogReplayFailForWrongDatabase"); + TestRunner.RunTestScript("Test-CancelManagedDatabaseLogReplayFailForWrongDatabase"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceActiveDirectoryAdministratorTests.cs b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceActiveDirectoryAdministratorTests.cs index 95cbe24af062..8f498251e622 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceActiveDirectoryAdministratorTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceActiveDirectoryAdministratorTests.cs @@ -20,26 +20,18 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ManagedInstanceActiveDirectoryAdministratorTests : SqlTestsBase + public class ManagedInstanceActiveDirectoryAdministratorTests : SqlTestRunner { public ManagedInstanceActiveDirectoryAdministratorTests(ITestOutputHelper output) : base(output) { - } - - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var newResourcesClient = GetResourcesClient(context); - var sqlClient = GetSqlClient(context); - var networkClient = GetNetworkClient(context); - var graphClient = GetGraphClientVersion1_6(context); - Helper.SetupSomeOfManagementClients(newResourcesClient,sqlClient, networkClient, graphClient); + } [Fact(Skip = "MDCS Customer Experience team should re-record this test.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceActiveDirectoryAdministrator() { - RunPowerShellTest("Test-ManagedInstanceActiveDirectoryAdministrator"); + TestRunner.RunTestScript("Test-ManagedInstanceActiveDirectoryAdministrator"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceKeyVaultKeyTests.cs b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceKeyVaultKeyTests.cs index 9a3ab0696ece..4cbca5ffcee5 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceKeyVaultKeyTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceKeyVaultKeyTests.cs @@ -20,58 +20,46 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ManagedInstanceKeyVaultKeyTests : SqlTestsBase + public class ManagedInstanceKeyVaultKeyTests : SqlTestRunner { public ManagedInstanceKeyVaultKeyTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances" - }; - } - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var graphClient = GetGraphClient(context); - var networkClient = GetNetworkClient(context); - var keyVaultClient = GetKeyVaultClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient, graphClient, keyVaultClient); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceKeyVaultKeyCI() { - RunPowerShellTest("Test-ManagedInstanceKeyVaultKeyCI"); + TestRunner.RunTestScript("Test-ManagedInstanceKeyVaultKeyCI"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceKeyVaultKey() { - RunPowerShellTest("Test-ManagedInstanceKeyVaultKey"); + TestRunner.RunTestScript("Test-ManagedInstanceKeyVaultKey"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceKeyVaultKeyInputObject() { - RunPowerShellTest("Test-ManagedInstanceKeyVaultKeyInputObject"); + TestRunner.RunTestScript("Test-ManagedInstanceKeyVaultKeyInputObject"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceKeyVaultKeyResourceId() { - RunPowerShellTest("Test-ManagedInstanceKeyVaultKeyResourceId"); + TestRunner.RunTestScript("Test-ManagedInstanceKeyVaultKeyResourceId"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestManagedInstanceKeyVaultKeyPiping() { - RunPowerShellTest("Test-ManagedInstanceKeyVaultKeyPiping"); + TestRunner.RunTestScript("Test-ManagedInstanceKeyVaultKeyPiping"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceProtectorTests.cs b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceProtectorTests.cs index 7c17af52fe9a..1ebcb7b92586 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceProtectorTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ManagedInstanceProtectorTests.cs @@ -20,93 +20,81 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ManagedInstanceProtectorTests : SqlTestsBase + public class ManagedInstanceProtectorTests : SqlTestRunner { public ManagedInstanceProtectorTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances" - }; - } - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var graphClient = GetGraphClient(context); - var networkClient = GetNetworkClient(context); - var keyVaultClient = GetKeyVaultClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient, graphClient, keyVaultClient); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorCI() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorCI"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorCI"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorByokFailsWithoutKeyId() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorByokFailsWithoutKeyId"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorByokFailsWithoutKeyId"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorServiceManaged() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorServiceManaged"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorServiceManaged"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorServiceManagedInputObject() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedInputObject"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedInputObject"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorServiceManagedResourceId() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedResourceId"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedResourceId"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorServiceManagedPiping() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedPiping"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorServiceManagedPiping"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorByok() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorByok"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorByok"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorByokInputObject() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorByokInputObject"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorByokInputObject"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorByokResourceId() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorByokResourceId"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorByokResourceId"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestSetGetManagedInstanceEncryptionProtectorByokPiping() { - RunPowerShellTest("Test-SetGetManagedInstanceEncryptionProtectorByokPiping"); + TestRunner.RunTestScript("Test-SetGetManagedInstanceEncryptionProtectorByokPiping"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/RecommendedActionTests.cs b/src/Sql/Sql.Test/ScenarioTests/RecommendedActionTests.cs index 5d4b0cd4b3e1..875bed16ec0f 100644 --- a/src/Sql/Sql.Test/ScenarioTests/RecommendedActionTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/RecommendedActionTests.cs @@ -19,7 +19,7 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class RecommendedActionTests : SqlTestsBase + public class RecommendedActionTests : SqlTestRunner { public RecommendedActionTests(ITestOutputHelper output) : base(output) { @@ -31,21 +31,21 @@ public RecommendedActionTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListServerRecommendedActions() { - RunPowerShellTest("Test-ListServerRecommendedActions"); + TestRunner.RunTestScript("Test-ListServerRecommendedActions"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetServerRecommendedAction() { - RunPowerShellTest("Test-GetServerRecommendedAction"); + TestRunner.RunTestScript("Test-GetServerRecommendedAction"); } [Fact(Skip = "This action is not supported on backend. Verified with feature owners.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateServerRecommendedAction() { - RunPowerShellTest("Test-UpdateServerRecommendedAction"); + TestRunner.RunTestScript("Test-UpdateServerRecommendedAction"); } #endregion @@ -56,21 +56,21 @@ public void TestUpdateServerRecommendedAction() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListDatabaseRecommendedActions() { - RunPowerShellTest("Test-ListDatabaseRecommendedActions"); + TestRunner.RunTestScript("Test-ListDatabaseRecommendedActions"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetDatabaseRecommendedAction() { - RunPowerShellTest("Test-GetDatabaseRecommendedAction"); + TestRunner.RunTestScript("Test-GetDatabaseRecommendedAction"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateDatabaseRecommendedAction() { - RunPowerShellTest("Test-UpdateDatabaseRecommendedAction"); + TestRunner.RunTestScript("Test-UpdateDatabaseRecommendedAction"); } #endregion @@ -81,21 +81,21 @@ public void TestUpdateDatabaseRecommendedAction() [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestListElasticPoolRecommendedActions() { - RunPowerShellTest("Test-ListElasticPoolRecommendedActions"); + TestRunner.RunTestScript("Test-ListElasticPoolRecommendedActions"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestGetElasticPoolRecommendedAction() { - RunPowerShellTest("Test-GetElasticPoolRecommendedAction"); + TestRunner.RunTestScript("Test-GetElasticPoolRecommendedAction"); } [Fact(Skip = "This action is not supported on backend. Verified with feature owners.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestUpdateElasticPoolRecommendedAction() { - RunPowerShellTest("Test-UpdateElasticPoolRecommendedAction"); + TestRunner.RunTestScript("Test-UpdateElasticPoolRecommendedAction"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/RecommendedElasticPoolTests.cs b/src/Sql/Sql.Test/ScenarioTests/RecommendedElasticPoolTests.cs index dca399542894..6c01bb1e822b 100644 --- a/src/Sql/Sql.Test/ScenarioTests/RecommendedElasticPoolTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/RecommendedElasticPoolTests.cs @@ -19,17 +19,18 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class RecommendedElasticPoolTests : SqlTestsBase + public class RecommendedElasticPoolTests : SqlTestRunner { public RecommendedElasticPoolTests(ITestOutputHelper output) : base(output) { + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ListRecommendedElasticPools() { - RunPowerShellTest("Test-ElasticPoolRecommendation"); + TestRunner.RunTestScript("Test-ElasticPoolRecommendation"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ServerActiveDirectoryAdministratorTest.cs b/src/Sql/Sql.Test/ScenarioTests/ServerActiveDirectoryAdministratorTest.cs index c5b0b0ce7c4c..580fa630c426 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ServerActiveDirectoryAdministratorTest.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ServerActiveDirectoryAdministratorTest.cs @@ -19,17 +19,18 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ServerActiveDirectoryAdministratorTest : SqlTestsBase + public class ServerActiveDirectoryAdministratorTest : SqlTestRunner { public ServerActiveDirectoryAdministratorTest(ITestOutputHelper output) : base(output) { + } [Fact(Skip = "SQL team hould re-record this test.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestServerActiveDirectoryAdministratorCRUD() { - RunPowerShellTest("Test-ServerActiveDirectoryAdministrator"); + TestRunner.RunTestScript("Test-ServerActiveDirectoryAdministrator"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ServerCommunicationLinkCrudTests.cs b/src/Sql/Sql.Test/ScenarioTests/ServerCommunicationLinkCrudTests.cs index 31a6213c5a8d..68f1f666af26 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ServerCommunicationLinkCrudTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ServerCommunicationLinkCrudTests.cs @@ -19,34 +19,32 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ServerCommunicationLinkCrudTests : SqlTestsBase + public class ServerCommunicationLinkCrudTests : SqlTestRunner { public ServerCommunicationLinkCrudTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestServerCommunicationLinkCreate() { - RunPowerShellTest("Test-CreateServerCommunicationLink"); + TestRunner.RunTestScript("Test-CreateServerCommunicationLink"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestServerCommunicationLinkGet() { - RunPowerShellTest("Test-GetServerCommunicationLink"); + TestRunner.RunTestScript("Test-GetServerCommunicationLink"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestServerCommunicationLinkRemove() { - RunPowerShellTest("Test-RemoveServerCommunicationLink"); + TestRunner.RunTestScript("Test-RemoveServerCommunicationLink"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ServerDisasterRecoveryConfigurationTests.cs b/src/Sql/Sql.Test/ScenarioTests/ServerDisasterRecoveryConfigurationTests.cs index 2ee2820dd2d6..8f5790384e41 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ServerDisasterRecoveryConfigurationTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ServerDisasterRecoveryConfigurationTests.cs @@ -19,17 +19,18 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ServerDisasterRecoveryConfigurationTests : SqlTestsBase + public class ServerDisasterRecoveryConfigurationTests : SqlTestRunner { public ServerDisasterRecoveryConfigurationTests(ITestOutputHelper output) : base(output) { + } [Fact(Skip = "TODO fix the test failure")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestServerDisasterRecoveryConfiguration() { - RunPowerShellTest("Test-ServerDisasterRecoveryConfiguration"); + TestRunner.RunTestScript("Test-ServerDisasterRecoveryConfiguration"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ServerKeyVaultKeyTests.cs b/src/Sql/Sql.Test/ScenarioTests/ServerKeyVaultKeyTests.cs index 8e7cb7a2b451..64fb7a83c799 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ServerKeyVaultKeyTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ServerKeyVaultKeyTests.cs @@ -20,20 +20,8 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ServerKeyVaultKeyTests : SqlTestsBase + public class ServerKeyVaultKeyTests : SqlTestRunner { - - - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - var graphClient = GetGraphClient(context); - var networkClient = GetNetworkClient(context); - var keyVaultClient = GetKeyVaultClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient, networkClient, graphClient, keyVaultClient); - } - public ServerKeyVaultKeyTests(ITestOutputHelper output) : base(output) { base.resourceTypesToIgnoreApiVersion = new string[] { @@ -45,21 +33,21 @@ public ServerKeyVaultKeyTests(ITestOutputHelper output) : base(output) [Trait(Category.RunType, Category.LiveOnly)] public void TestServerKeyVaultKeyAdd() { - RunPowerShellTest("Test-AddServerKeyVaultKey"); + TestRunner.RunTestScript("Test-AddServerKeyVaultKey"); } [Fact(Skip = "Requires hardcoded resource 'akvtdekeyvaultcl'")] [Trait(Category.RunType, Category.LiveOnly)] public void TestServerKeyVaultKeyGet() { - RunPowerShellTest("Test-GetServerKeyVaultKey"); + TestRunner.RunTestScript("Test-GetServerKeyVaultKey"); } [Fact(Skip = "TODO: only works for live mode. Mihymel will fix the test issue for Create-ServerKeyVaultKeyTestEnvironment")] [Trait(Category.RunType, Category.LiveOnly)] public void TestServerKeyVaultKeyRemove() { - RunPowerShellTest("Test-RemoveServerKeyVaultKey"); + TestRunner.RunTestScript("Test-RemoveServerKeyVaultKey"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ServiceTierAdvisorTests.cs b/src/Sql/Sql.Test/ScenarioTests/ServiceTierAdvisorTests.cs index 68c1e650fc5c..5b384236bc10 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ServiceTierAdvisorTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ServiceTierAdvisorTests.cs @@ -19,27 +19,25 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ServiceTierAdvisorTests : SqlTestsBase + public class ServiceTierAdvisorTests : SqlTestRunner { public ServiceTierAdvisorTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void GetUpgradeDatabaseHint() { - RunPowerShellTest("Test-GetUpgradeDatabaseHint"); + TestRunner.RunTestScript("Test-GetUpgradeDatabaseHint"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void GetUpgradeServerHint() { - RunPowerShellTest("Test-GetUpgradeServerHint"); + TestRunner.RunTestScript("Test-GetUpgradeServerHint"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/SqlTestRunner.cs b/src/Sql/Sql.Test/ScenarioTests/SqlTestRunner.cs index 45f1297fc3d5..505dc5367413 100644 --- a/src/Sql/Sql.Test/ScenarioTests/SqlTestRunner.cs +++ b/src/Sql/Sql.Test/ScenarioTests/SqlTestRunner.cs @@ -29,6 +29,7 @@ using Microsoft.Azure.Graph.RBAC; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.TestFx; +using Microsoft.Azure.Commands.TestFx.Recorder; namespace Microsoft.Azure.Commands.ScenarioTest.SqlTests { @@ -88,18 +89,6 @@ protected SqlTestRunner(ITestOutputHelper output) {"Microsoft.Insights", null}, {"Microsoft.OperationalInsights", null} } - ).WithManagementClients( - GetSqlClient, - GetMonitorManagementClient, - GetCommonMonitorManagementClient, - GetEventHubManagementClient, - GetOperationalInsightsManagementClient, - GetResourcesClient, - GetGraphClient, - GetGraphClientVersion1_6, - GetKeyVaultClient, - GetNetworkClient, - GetStorageManagementClient ) .Build(); } @@ -138,7 +127,7 @@ protected GraphRbacManagementClient GetGraphClient(MockContext context) { GraphRbacManagementClient graphClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); graphClient.BaseUri = TestEnvironmentFactory.GetTestEnvironment().Endpoints.GraphUri; - graphClient.TenantID = TestEnvironmentFactory.GetTestEnvironment().Tenant; + graphClient.TenantID = TestEnvironmentFactory.GetTestEnvironment().TenantId; return graphClient; } @@ -150,7 +139,7 @@ protected Microsoft.Azure.Graph.RBAC.Version1_6.GraphRbacManagementClient GetGra if (HttpMockServer.Mode == HttpRecorderMode.Record) { - tenantId = TestEnvironmentFactory.GetTestEnvironment().Tenant; + tenantId = TestEnvironmentFactory.GetTestEnvironment().TenantId; HttpMockServer.Variables[TenantIdKey] = tenantId; } else if (HttpMockServer.Mode == HttpRecorderMode.Playback) diff --git a/src/Sql/Sql.Test/ScenarioTests/SqlTestsBase.cs b/src/Sql/Sql.Test/ScenarioTests/SqlTestsBase.cs deleted file mode 100644 index 646540d2237f..000000000000 --- a/src/Sql/Sql.Test/ScenarioTests/SqlTestsBase.cs +++ /dev/null @@ -1,199 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Management.Network; -using Microsoft.Azure.Test.HttpRecorder; -using Microsoft.WindowsAzure.Commands.ScenarioTest; -using Microsoft.WindowsAzure.Commands.Test.Utilities.Common; -using System; -using System.IO; -using System.Collections.Generic; -using System.Diagnostics; -using Microsoft.Azure.Management.Internal.Resources; -using Microsoft.Azure.Management.Sql; -using CommonStorage = Microsoft.Azure.Management.Storage.Version2017_10_01; -using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Xunit.Abstractions; -using Microsoft.Azure.Management.EventHub; -using Microsoft.Azure.Management.OperationalInsights; -using SDKMonitor = Microsoft.Azure.Management.Monitor; -using CommonMonitor = Microsoft.Azure.Management.Monitor.Version2018_09_01; -using Microsoft.Azure.Management.KeyVault; -using Microsoft.Azure.Graph.RBAC; -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; - -namespace Microsoft.Azure.Commands.ScenarioTest.SqlTests -{ - public class SqlTestsBase : RMTestBase, IDisposable - { - protected EnvironmentSetupHelper Helper; - protected string[] resourceTypesToIgnoreApiVersion; - private const string TenantIdKey = "TenantId"; - - protected SqlTestsBase(ITestOutputHelper output) - { - Helper = new EnvironmentSetupHelper(); - - var tracer = new XunitTracingInterceptor(output); - XunitTracingInterceptor.AddToContext(tracer); - Helper.TracingInterceptor = tracer; - } - - protected virtual void SetupManagementClients(MockContext context) - { - var sqlClient = GetSqlClient(context); - var newResourcesClient = GetResourcesClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, newResourcesClient); - } - - protected void RunPowerShellTest(params string[] scripts) - { - TestExecutionHelpers.SetUpSessionAndProfile(); - var sf = new StackTrace().GetFrame(1); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var mockName = sf.GetMethod().Name; - - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null}, - {"Microsoft.Network", null}, - {"Microsoft.KeyVault", null}, - {"Microsoft.EventHub", null}, - {"Microsoft.Insights", null}, - {"Microsoft.OperationalInsights", null} - }; - - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Graph.RBAC.Version1_6.GraphRbacManagementClient", "1.42-previewInternal"}, - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new PermissiveRecordMatcherWithResourceApiExclusion(true, d, providersToIgnore, resourceTypesToIgnoreApiVersion); - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); - - // Enable undo functionality as well as mock recording - using (var context = MockContext.Start(callingClassType, mockName)) - { - Helper.SetupEnvironment(AzureModule.AzureResourceManager); - SetupManagementClients(context); - Helper.SetupModules(AzureModule.AzureResourceManager, - "ScenarioTests\\Common.ps1", - "ScenarioTests\\" + GetType().Name + ".ps1", - Helper.RMProfileModule, - Helper.GetRMModulePath(@"AzureRM.Sql.psd1"), - Helper.RMNetworkModule, - "AzureRM.Storage.ps1", - "AzureRM.Resources.ps1", - Helper.RMOperationalInsightsModule, - Helper.RMEventHubModule, - Helper.RMMonitorModule, - Helper.RMKeyVaultModule); - Helper.RunPowerShellTest(scripts); - } - } - - protected SqlManagementClient GetSqlClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected SDKMonitor.IMonitorManagementClient GetMonitorManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected CommonMonitor.IMonitorManagementClient GetCommonMonitorManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected IEventHubManagementClient GetEventHubManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected IOperationalInsightsManagementClient GetOperationalInsightsManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected ResourceManagementClient GetResourcesClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected GraphRbacManagementClient GetGraphClient(MockContext context) - { - GraphRbacManagementClient graphClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - graphClient.BaseUri = TestEnvironmentFactory.GetTestEnvironment().Endpoints.GraphUri; - graphClient.TenantID = TestEnvironmentFactory.GetTestEnvironment().Tenant; - return graphClient; - } - - protected Microsoft.Azure.Graph.RBAC.Version1_6.GraphRbacManagementClient GetGraphClientVersion1_6(MockContext context) - { - Microsoft.Azure.Graph.RBAC.Version1_6.GraphRbacManagementClient graphClient = context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - graphClient.BaseUri = TestEnvironmentFactory.GetTestEnvironment().Endpoints.GraphUri; - string tenantId = null; - - if (HttpMockServer.Mode == HttpRecorderMode.Record) - { - tenantId = TestEnvironmentFactory.GetTestEnvironment().Tenant; - HttpMockServer.Variables[TenantIdKey] = tenantId; - } - else if (HttpMockServer.Mode == HttpRecorderMode.Playback) - { - if (HttpMockServer.Variables.ContainsKey(TenantIdKey)) - { - tenantId = HttpMockServer.Variables[TenantIdKey]; - } - } - graphClient.TenantID = tenantId; - if (AzureRmProfileProvider.Instance != null && - AzureRmProfileProvider.Instance.Profile != null && - AzureRmProfileProvider.Instance.Profile.DefaultContext != null && - AzureRmProfileProvider.Instance.Profile.DefaultContext.Tenant != null) - { - AzureRmProfileProvider.Instance.Profile.DefaultContext.Tenant.Id = tenantId; - } - return graphClient; - } - - protected KeyVaultManagementClient GetKeyVaultClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected NetworkManagementClient GetNetworkClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static CommonStorage.StorageManagementClient GetStorageManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - public void Dispose() - { - XunitTracingInterceptor.RemoveFromContext(Helper.TracingInterceptor); - Helper.TracingInterceptor = null; - Helper = null; - } - } -} diff --git a/src/Sql/Sql.Test/ScenarioTests/TDECertificateTests.cs b/src/Sql/Sql.Test/ScenarioTests/TDECertificateTests.cs index 6cbebaf7a1b5..350188dc580b 100644 --- a/src/Sql/Sql.Test/ScenarioTests/TDECertificateTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/TDECertificateTests.cs @@ -20,76 +20,74 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class TDECertificateTests : SqlTestsBase + public class TDECertificateTests : SqlTestRunner { public TDECertificateTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerDefaultParameterSetNoPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerDefaultParameterSetNoPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerDefaultParameterSetNoPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerDefaultParameterSetWithPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerDefaultParameterSetWithPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerDefaultParameterSetWithPassword"); } [Fact(Skip = "Skip due to long setup time for managed instance")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForManagedInstanceDefaultParameterSetNoPassword() { - RunPowerShellTest("Test-AddTdeCertificateForManagedInstanceDefaultParameterSetNoPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForManagedInstanceDefaultParameterSetNoPassword"); } [Fact(Skip = "Skip due to long setup time for managed instance")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForManagedInstanceDefaultParameterSetWithPassword() { - RunPowerShellTest("Test-AddTdeCertificateForManagedInstanceDefaultParameterSetWithPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForManagedInstanceDefaultParameterSetWithPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerInputObjectParameterSetWithPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerInputObjectParameterSetWithPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerInputObjectParameterSetWithPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerResourceIdParameterSetWithPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerResourceIdParameterSetWithPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerResourceIdParameterSetWithPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerInputObjectParameterSetNoPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerInputObjectParameterSetNoPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerInputObjectParameterSetNoPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerResourceIdParameterSetNoPassword() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerResourceIdParameterSetNoPassword"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerResourceIdParameterSetNoPassword"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void TestAddTdeCertificateForSqlServerWithPiping() { - RunPowerShellTest("Test-AddTdeCertificateForSqlServerWithPiping"); + TestRunner.RunTestScript("Test-AddTdeCertificateForSqlServerWithPiping"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionClassicStorageTests.cs b/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionClassicStorageTests.cs index 5caecb728c19..3d1bbdd706f0 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionClassicStorageTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionClassicStorageTests.cs @@ -20,16 +20,8 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ThreatDetectionClassicStorageTests : SqlTestsBase + public class ThreatDetectionClassicStorageTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var storageV2Client = GetStorageManagementClient(context); - var newResourcesClient = GetResourcesClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, storageV2Client, newResourcesClient); - } - public ThreatDetectionClassicStorageTests(ITestOutputHelper output) : base(output) { } @@ -40,7 +32,7 @@ public ThreatDetectionClassicStorageTests(ITestOutputHelper output) : base(outpu // See issue https://github.com/Azure/azure-powershell/issues/6601 public void ThreatDetectionUpdatePolicyWithClassicStorage() { - RunPowerShellTest("Test-ThreatDetectionUpdatePolicyWithClassicStorage"); + TestRunner.RunTestScript("Test-ThreatDetectionUpdatePolicyWithClassicStorage"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionTests.cs b/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionTests.cs index e5b06acff212..7e9a7b39ae1f 100644 --- a/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/ThreatDetectionTests.cs @@ -20,56 +20,46 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class ThreatDetectionTests : SqlTestsBase + public class ThreatDetectionTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var storageV2Client = GetStorageManagementClient(context); - var newResourcesClient = GetResourcesClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, storageV2Client, newResourcesClient); - } - public ThreatDetectionTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers" - }; + } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ThreatDetectionGetDefaultPolicy() { - RunPowerShellTest("Test-ThreatDetectionGetDefaultPolicy"); + TestRunner.RunTestScript("Test-ThreatDetectionGetDefaultPolicy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ThreatDetectionDatabaseUpdatePolicy() { - RunPowerShellTest("Test-ThreatDetectionDatabaseUpdatePolicy"); + TestRunner.RunTestScript("Test-ThreatDetectionDatabaseUpdatePolicy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void ThreatDetectionServerUpdatePolicy() { - RunPowerShellTest("Test-ThreatDetectionServerUpdatePolicy"); + TestRunner.RunTestScript("Test-ThreatDetectionServerUpdatePolicy"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void DisablingThreatDetection() { - RunPowerShellTest("Test-DisablingThreatDetection"); + TestRunner.RunTestScript("Test-DisablingThreatDetection"); } [Fact] [Trait(Category.AcceptanceType, Category.CheckIn)] public void InvalidArgumentsThreatDetection() { - RunPowerShellTest("Test-InvalidArgumentsThreatDetection"); + TestRunner.RunTestScript("Test-InvalidArgumentsThreatDetection"); } } } diff --git a/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentMiTests.cs b/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentMiTests.cs index fcd116159640..8e4370f20e26 100644 --- a/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentMiTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentMiTests.cs @@ -20,23 +20,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class VulnerabilityAssessmentMiTests : SqlTestsBase + public class VulnerabilityAssessmentMiTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var storageV2Client = GetStorageManagementClient(context); - var newResourcesClient = GetResourcesClient(context); - var networkClient = GetNetworkClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, storageV2Client, newResourcesClient, networkClient); - } - public VulnerabilityAssessmentMiTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/managedInstances", - "Microsoft.Sql/managedInstances/databases" - }; + } #region Managed Instance Policy Tests @@ -45,7 +33,7 @@ public VulnerabilityAssessmentMiTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedInstanceSettingsTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedInstanceSettingsTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedInstanceSettingsTest"); } #endregion @@ -56,14 +44,14 @@ public void VulnerabilityAssessmentManagedInstanceSettingsTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedDatabaseWithSettingsNotDefinedTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedDatabaseWithSettingsNotDefinedTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedDatabaseWithSettingsNotDefinedTest"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedDatabaseSettingsTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedDatabaseSettingsTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedDatabaseSettingsTest"); } #endregion @@ -74,7 +62,7 @@ public void VulnerabilityAssessmentManagedDatabaseSettingsTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedDatabaseBaselineTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedDatabaseBaselineTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedDatabaseBaselineTest"); } #endregion @@ -85,14 +73,14 @@ public void VulnerabilityAssessmentManagedDatabaseBaselineTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedDatabaseScanRecordGetListTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedDatabaseScanRecordGetListTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedDatabaseScanRecordGetListTest"); } [Fact(Skip = "Requires manual set up.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentManagedDatabaseScanConvertTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentManagedDatabaseScanConvertTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentManagedDatabaseScanConvertTest"); } #endregion diff --git a/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentTests.cs b/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentTests.cs index 798bada0aa63..f1a2d52c50cd 100644 --- a/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentTests.cs +++ b/src/Sql/Sql.Test/ScenarioTests/VulnerabilityAssessmentTests.cs @@ -20,23 +20,11 @@ namespace Microsoft.Azure.Commands.Sql.Test.ScenarioTests { - public class VulnerabilityAssessmentTests : SqlTestsBase + public class VulnerabilityAssessmentTests : SqlTestRunner { - protected override void SetupManagementClients(RestTestFramework.MockContext context) - { - var sqlClient = GetSqlClient(context); - var storageV2Client = GetStorageManagementClient(context); - var newResourcesClient = GetResourcesClient(context); - Helper.SetupSomeOfManagementClients(sqlClient, storageV2Client, newResourcesClient); - } - public VulnerabilityAssessmentTests(ITestOutputHelper output) : base(output) { - base.resourceTypesToIgnoreApiVersion = new string[] { - "Microsoft.Sql/servers", - "Microsoft.Sql/managedInstances", - "Microsoft.Sql/managedInstances/databases" - }; + } #region Server Policy Tests @@ -45,7 +33,7 @@ public VulnerabilityAssessmentTests(ITestOutputHelper output) : base(output) [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentServerSettingsTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentServerSettingsTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentServerSettingsTest"); } #endregion @@ -56,14 +44,14 @@ public void VulnerabilityAssessmentServerSettingsTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentWithSettingsNotDefinedTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentWithSettingsNotDefinedTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentWithSettingsNotDefinedTest"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentSettingsTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentSettingsTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentSettingsTest"); } #endregion @@ -74,7 +62,7 @@ public void VulnerabilityAssessmentSettingsTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentBaselineTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentBaselineTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentBaselineTest"); } #endregion @@ -85,14 +73,14 @@ public void VulnerabilityAssessmentBaselineTest() [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentScanRecordGetListTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentScanRecordGetListTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentScanRecordGetListTest"); } [Fact(Skip = "Cannot re-record.")] [Trait(Category.AcceptanceType, Category.CheckIn)] public void VulnerabilityAssessmentScanConvertTest() { - RunPowerShellTest("Test-VulnerabilityAssessmentScanConvertTest"); + TestRunner.RunTestScript("Test-VulnerabilityAssessmentScanConvertTest"); } #endregion diff --git a/src/Sql/Sql.Test/UnitTests/PermissiveRecordMatcherWithResourceApiExclusionUnitTests.cs b/src/Sql/Sql.Test/UnitTests/PermissiveRecordMatcherWithResourceApiExclusionUnitTests.cs index 86caf9627690..3d747bfcd54a 100644 --- a/src/Sql/Sql.Test/UnitTests/PermissiveRecordMatcherWithResourceApiExclusionUnitTests.cs +++ b/src/Sql/Sql.Test/UnitTests/PermissiveRecordMatcherWithResourceApiExclusionUnitTests.cs @@ -1,4 +1,5 @@ -using Microsoft.WindowsAzure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Recorder; +using Microsoft.WindowsAzure.Commands.ScenarioTest; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/SqlVirtualMachine/SqlVirtualMachine.Test/ScenarioTests/SqlVirtualMachineTestRunner.cs b/src/SqlVirtualMachine/SqlVirtualMachine.Test/ScenarioTests/SqlVirtualMachineTestRunner.cs index b79fad5bf66e..e9d2b33aa1fc 100644 --- a/src/SqlVirtualMachine/SqlVirtualMachine.Test/ScenarioTests/SqlVirtualMachineTestRunner.cs +++ b/src/SqlVirtualMachine/SqlVirtualMachine.Test/ScenarioTests/SqlVirtualMachineTestRunner.cs @@ -16,6 +16,7 @@ using Xunit.Abstractions; using Microsoft.Azure.Commands.TestFx; using Microsoft.WindowsAzure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Recorder; namespace Microsoft.Azure.Commands.SqlVirtualMachine.Test.ScenarioTests { diff --git a/src/StorageSync/StorageSync.Test/ScenarioTests/StorageSyncTestRunner.cs b/src/StorageSync/StorageSync.Test/ScenarioTests/StorageSyncTestRunner.cs index f01c9adb4b91..39e4b83896a2 100644 --- a/src/StorageSync/StorageSync.Test/ScenarioTests/StorageSyncTestRunner.cs +++ b/src/StorageSync/StorageSync.Test/ScenarioTests/StorageSyncTestRunner.cs @@ -15,12 +15,12 @@ using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.StorageSync.Common; using Microsoft.Azure.Commands.StorageSync.Interfaces; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using StorageSync.Test.Common; using System.Collections.Generic; using System.Diagnostics; using Microsoft.Azure.Commands.TestFx; using Xunit.Abstractions; +using Microsoft.Azure.Test.HttpRecorder; namespace ScenarioTests { @@ -29,12 +29,6 @@ namespace ScenarioTests /// public class StorageSyncTestRunner { - /// - /// Gets the user domain. - /// - /// The user domain. - public string UserDomain { get; private set; } - protected readonly ITestRunner TestRunner; protected StorageSyncTestRunner(ITestOutputHelper output) @@ -67,27 +61,14 @@ protected StorageSyncTestRunner(ITestOutputHelper output) {"Microsoft.Storage", null}, {"Microsoft.StorageSync", null} } - ).WithMockContextAction(() => - { - var sf = new StackTrace().GetFrame(2); - var callingClassType = sf.GetMethod().ReflectedType?.ToString(); - var testName = sf.GetMethod().Name; - - using (var context = MockContext.Start(callingClassType, testName)) - { - RegisterComponents(context, testName); - } - } - ) + ).WithMockContextAction(mockContext => + { + RegisterComponents(HttpMockServer.TestIdentity); + }) .Build(); } - /// - /// Registers the components. - /// - /// The context. - /// Name of the test. - private void RegisterComponents(MockContext context, string testName) + private void RegisterComponents(string testName) { AzureSession.Instance.RegisterComponent(StorageSyncConstants.StorageSyncResourceManager, () => new MockStorageSyncResourceManager(testName), overwrite: true); } diff --git a/src/Synapse/Synapse.Test/ScenarioTests/SynapseTestRunner.cs b/src/Synapse/Synapse.Test/ScenarioTests/SynapseTestRunner.cs index 1cfa9ed21f2a..c51af0e056d8 100644 --- a/src/Synapse/Synapse.Test/ScenarioTests/SynapseTestRunner.cs +++ b/src/Synapse/Synapse.Test/ScenarioTests/SynapseTestRunner.cs @@ -81,66 +81,11 @@ protected SynapseTestRunner(ITestOutputHelper output) {"Microsoft.OperationalInsights", null} } ).WithManagementClients( - GetResourceManagementClient, - GetStorageManagementClient, - GetNewSynapseManagementClient, - GetSynapseManagementClient, - GetSynapseSqlV3ManagementClient, - GetCommonMonitorManagementClient, - GetMonitorManagementClient, - GetOperationalInsightsManagementClient, - GetEventHubManagementClient, GetSynapseClient ) .Build(); } - #region client creation helpers - protected static NewResourceManagementClient GetResourceManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static StorageManagementClient GetStorageManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static NewStorageManagementClient GetNewSynapseManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static SynapseManagementClient GetSynapseManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static SynapseSqlV3ManagementClient GetSynapseSqlV3ManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static CommonMonitor.MonitorManagementClient GetCommonMonitorManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static SDKMonitor.MonitorManagementClient GetMonitorManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static OperationalInsightsManagementClient GetOperationalInsightsManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - - protected static EventHubManagementClient GetEventHubManagementClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } - protected static SynapseClient GetSynapseClient(MockContext context) { string environmentConnectionString = Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION"); @@ -153,7 +98,7 @@ protected static SynapseClient GetSynapseClient(MockContext context) var connectionInfo = new ConnectionString(Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION")); string servicePrincipal = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalKey); string servicePrincipalSecret = connectionInfo.GetValue(ConnectionStringKeys.ServicePrincipalSecretKey); - string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.AADTenantKey); + string aadTenant = connectionInfo.GetValue(ConnectionStringKeys.TenantIdKey); // Create credentials var clientCredentials = new ClientCredential(servicePrincipal, servicePrincipalSecret); @@ -163,6 +108,5 @@ protected static SynapseClient GetSynapseClient(MockContext context) return new SynapseClient(new TokenCredentials(accessToken), HttpMockServer.CreateInstance()); } - #endregion } } diff --git a/tools/Common.Netcore.Dependencies.Test.targets b/tools/Common.Netcore.Dependencies.Test.targets index 51cd625eb3fc..df5cada97d66 100644 --- a/tools/Common.Netcore.Dependencies.Test.targets +++ b/tools/Common.Netcore.Dependencies.Test.targets @@ -8,9 +8,7 @@ - - @@ -44,4 +42,4 @@ - \ No newline at end of file + diff --git a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcher.cs b/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcher.cs deleted file mode 100644 index 5fb7fc4d4ee2..000000000000 --- a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcher.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.Test.HttpRecorder; -using System; -using System.Text; - -namespace Microsoft.WindowsAzure.Commands.ScenarioTest -{ - public class PermissiveRecordMatcher : IRecordMatcher - { - public string GetMatchingKey(System.Net.Http.HttpRequestMessage request) - { - var path = request.RequestUri.PathAndQuery; - if (path.Contains("?&")) - { - path = path.Replace("?&", "?"); - } - - var encodedPath = Convert.ToBase64String(Encoding.UTF8.GetBytes(path)); - return string.Format("{0} {1}", request.Method, encodedPath); - } - - public string GetMatchingKey(RecordEntry recordEntry) - { - var encodedPath = recordEntry.EncodedRequestUri; - if (recordEntry.RequestUri.Contains("?&")) - { - var updatedPath = recordEntry.RequestUri.Replace("?&", "?"); - encodedPath = Convert.ToBase64String(Encoding.UTF8.GetBytes(updatedPath)); - } - - return string.Format("{0} {1}", recordEntry.RequestMethod, encodedPath); - } - } -} diff --git a/tools/ScenarioTest.ResourceManager/PowerShellExtensions.cs b/tools/ScenarioTest.ResourceManager/PowerShellExtensions.cs deleted file mode 100644 index c94fe4bda292..000000000000 --- a/tools/ScenarioTest.ResourceManager/PowerShellExtensions.cs +++ /dev/null @@ -1,257 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using Microsoft.Azure.ServiceManagement.Common.Models; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Management.Automation; -using System.Management.Automation.Runspaces; -using Microsoft.WindowsAzure.Commands.Utilities.Common; - -namespace Microsoft.WindowsAzure.Commands.ScenarioTest -{ - public static class PowerShellExtensions - { - public static string PowerShellEnvironmentFormat = "Set-Item env:{0} \"{1}\""; - public static string PowerShellVariableFormat = "${0}={1}"; - public static string CredentialImportFormat = "Import-AzurePublishSettingsFile '{0}'"; - - /// - /// Gets a powershell variable from the current session and converts it back to it's original type. - /// - /// The powershell object original type - /// The PowerShell instance - /// The variable name - /// The variable object - public static T GetPowerShellVariable(this System.Management.Automation.PowerShell powershell, string name) - { - object obj = powershell.Runspace.SessionStateProxy.GetVariable(name); - - if (obj is PSObject) - { - return (T)(obj as PSObject).BaseObject; - } - else - { - return (T)obj; - } - } - - /// - /// Gets a powershell enumerable collection from the current session and convernts it back to it's original type. - /// - /// The powershell object original type - /// The PowerShell instance - /// The variable name - /// The collection in list - public static List GetPowerShellCollection(this System.Management.Automation.PowerShell powershell, string name) - { - List result = new List(); - - try - { - object[] objects = (object[])powershell.Runspace.SessionStateProxy.GetVariable(name); - - foreach (object item in objects) - { - if (item is PSObject) - { - result.Add((T)(item as PSObject).BaseObject); - } - else - { - result.Add((T)item); - } - } - } - catch (Exception) { /* Do nothing */ } - - return result; - } - - /// - /// Sets a new PSVariable to the current scope. - /// - /// The PowerShell instance - /// The variable name - /// The variable value - public static void SetVariable(this System.Management.Automation.PowerShell powershell, string name, object value) - { - powershell.Runspace.SessionStateProxy.SetVariable(name, value); - } - - /// - /// Logs a PowerShell exception thrown from PowerShell.Invoke, parsing the inner - /// PowerShell error record if available - /// - /// The exception to parse - public static void LogPowerShellException( - this System.Management.Automation.PowerShell powershell, - Exception runtimeException, - XunitTracingInterceptor xunitLogger) - { - if (xunitLogger != null) - { - xunitLogger.Information(string.Format("Caught Exception: {0}", runtimeException)); - xunitLogger.Information(string.Format("Message: {0}", runtimeException.Message)); - } - - IContainsErrorRecord recordContainer = runtimeException as IContainsErrorRecord; - if (recordContainer != null) - { - ErrorRecord record = recordContainer.ErrorRecord; - - if (xunitLogger != null) - { - xunitLogger.Information(FormatErrorRecord(record)); - } - } - - if (runtimeException.InnerException != null) - { - powershell.LogPowerShellException(runtimeException.InnerException, xunitLogger); - } - } - - /// - /// Log the PowerShell Streams from a PowerShell invocation - /// - /// The PowerShell instance to log - public static void LogPowerShellResults( - this System.Management.Automation.PowerShell powershell, - XunitTracingInterceptor xunitLogger) - { - powershell.LogPowerShellResults(null, xunitLogger); - } - - /// - /// Log the PowerShell Streams from a PowerShell invocation - /// - /// The PowerShell instance to log - public static void LogPowerShellResults( - this System.Management.Automation.PowerShell powershell, - Collection output, - XunitTracingInterceptor xunitLogger) - { - if (output != null) - { - LogPowerShellStream(xunitLogger, output, "OUTPUT"); - } - - if (xunitLogger != null && - powershell.Commands != null && - powershell.Commands.Commands != null && - powershell.Commands.Commands.Count > 0) - { - xunitLogger.Information("================== COMMANDS =======================\n"); - foreach (Command command in powershell.Commands.Commands) - { - xunitLogger.Information(string.Format("{0}\n", command.CommandText)); - } - - xunitLogger.Information("===================================================\n"); - } - - LogPowerShellStream(xunitLogger, powershell.Streams.Debug, "DEBUG"); - LogPowerShellStream(xunitLogger, powershell.Streams.Error.Select(FormatErrorRecord).ToList(), "ERROR"); - LogPowerShellStream(xunitLogger, powershell.Streams.Progress, "PROGRESS"); - LogPowerShellStream(xunitLogger, powershell.Streams.Verbose, "VERBOSE"); - LogPowerShellStream(xunitLogger, powershell.Streams.Warning, "WARNING"); - } - - /// - /// Formats an to a detailed string for logging. - /// - internal static string FormatErrorRecord(ErrorRecord record) - { - return String.Format( - "PowerShell Error Record: {0}\nException:{1}\nDetails:{2}\nScript Stack Trace: {3}\n: Target: {4}\n", - record, - record.Exception, - record.ErrorDetails, - record.ScriptStackTrace, - record.TargetObject); - } - - /// - /// Add an environment variable to the PowerShell instance - /// - /// The powershell instance to alter - /// The variable name - /// The variable value - public static void AddEnvironmentVariable(this System.Management.Automation.PowerShell powerShell, string variableKey, string variableValue) - { - powerShell.AddScript(string.Format(PowerShellEnvironmentFormat, variableKey, variableValue)); - } - - /// - /// Add an environment variable to the PowerShell instance - /// - /// The powershell instance to alter - /// The variable name - /// The variable value - public static void AddPowerShellVariable(this System.Management.Automation.PowerShell powerShell, string variableKey, string variableValue) - { - powerShell.AddScript(string.Format(PowerShellVariableFormat, variableKey, variableValue)); - } - /// - /// Import credentials into PowerShell - /// - /// The PowerShell instance to alter - /// The fully qualified path top the credentials - public static void ImportCredentials(this System.Management.Automation.PowerShell powerShell, string credentialPath) - { - powerShell.AddScript(string.Format(CredentialImportFormat, credentialPath)); - } - - /// - /// Remove all credentials for the current user - /// - /// The PowerShell instance to use for removing credentials - public static void RemoveCredentials(this System.Management.Automation.PowerShell powerShell) - { - powerShell.AddScript("try {$sub = Get-AzureSubscription | Remove-AzureSubscription -Force} catch {}"); - } - - /// - /// Log a single PowerShell stream, using the given name - /// - /// The type of the internal data record (different for every stream) - /// The stream to log - /// The name of the stream to print in the log - private static void LogPowerShellStream( - XunitTracingInterceptor xunitLogger, - ICollection stream, - string name) - { - if (xunitLogger != null && stream != null && stream.Count > 0) - { - xunitLogger.Information("---------------------------------------------------------------\n"); - xunitLogger.Information(string.Format("{0} STREAM\n", name)); - xunitLogger.Information("---------------------------------------------------------------\n"); - foreach (T item in stream) - { - if (item != null) - { - xunitLogger.Information(string.Format("{0}\n", item.ToString())); - } - } - xunitLogger.Information("---------------------------------------------------------------\n"); - xunitLogger.Information(""); - } - } - } -} diff --git a/tools/ScenarioTest.ResourceManager/ScenarioTest.ResourceManager.csproj b/tools/ScenarioTest.ResourceManager/ScenarioTest.ResourceManager.csproj index 2fcf2a0f5418..054cc694d0e6 100644 --- a/tools/ScenarioTest.ResourceManager/ScenarioTest.ResourceManager.csproj +++ b/tools/ScenarioTest.ResourceManager/ScenarioTest.ResourceManager.csproj @@ -11,6 +11,152 @@ $(LegacyAssemblyPrefix)ScenarioTest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -20,23 +166,4 @@ - - - PreserveNewest - Content - - - PreserveNewest - Content - - - PreserveNewest - Content - - - PreserveNewest - Content - - - \ No newline at end of file diff --git a/tools/ScenarioTest.ResourceManager/Assert.ps1 b/tools/TestFx/Assert.ps1 similarity index 100% rename from tools/ScenarioTest.ResourceManager/Assert.ps1 rename to tools/TestFx/Assert.ps1 diff --git a/tools/ScenarioTest.ResourceManager/AzureRM.Resources.ps1 b/tools/TestFx/AzureRM.Resources.ps1 similarity index 100% rename from tools/ScenarioTest.ResourceManager/AzureRM.Resources.ps1 rename to tools/TestFx/AzureRM.Resources.ps1 diff --git a/tools/ScenarioTest.ResourceManager/AzureRM.Storage.ps1 b/tools/TestFx/AzureRM.Storage.ps1 similarity index 100% rename from tools/ScenarioTest.ResourceManager/AzureRM.Storage.ps1 rename to tools/TestFx/AzureRM.Storage.ps1 diff --git a/tools/ScenarioTest.ResourceManager/Common.ps1 b/tools/TestFx/Common.ps1 similarity index 100% rename from tools/ScenarioTest.ResourceManager/Common.ps1 rename to tools/TestFx/Common.ps1 diff --git a/tools/TestFx/ConnectionString.cs b/tools/TestFx/ConnectionString.cs new file mode 100644 index 000000000000..f0dd34050b4d --- /dev/null +++ b/tools/TestFx/ConnectionString.cs @@ -0,0 +1,204 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Text.RegularExpressions; + +namespace Microsoft.Azure.Commands.TestFx +{ + public class ConnectionString + { + private Dictionary _keyValuePairs; + private string _connString; + private StringBuilder _parseErrorSb; + private string DEFAULT_TENANTID = "72f988bf-86f1-41af-91ab-2d7cd011db47"; + + public Dictionary KeyValuePairs + { + get + { + if (_keyValuePairs == null) + { + _keyValuePairs = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + return _keyValuePairs; + } + private set + { + _keyValuePairs = value; + } + } + + public string ParseErrors + { + get + { + return _parseErrorSb.ToString(); + } + + private set + { + _parseErrorSb.AppendLine(value); + } + } + + void Init() + { + List connectionKeyNames = new List(); + connectionKeyNames = (from fi in typeof(ConnectionStringKeys).GetFields(BindingFlags.Public | BindingFlags.Static) + select fi.GetRawConstantValue().ToString()).ToList(); + connectionKeyNames.ForEach((li) => KeyValuePairs.Add(li, string.Empty)); + } + + public ConnectionString() + { + Init(); + _parseErrorSb = new StringBuilder(); + } + + public ConnectionString(string connString) : this() + { + _connString = connString; + Parse(_connString); //Keyvalue pairs are normalized and is called from Parse(string) function + NormalizeKeyValuePairs(); + } + + private void NormalizeKeyValuePairs() + { + string clientId, spn, password, spnSecret, userId, aadTenantId; + KeyValuePairs.TryGetValue(ConnectionStringKeys.AADClientIdKey, out clientId); + KeyValuePairs.TryGetValue(ConnectionStringKeys.ServicePrincipalKey, out spn); + + KeyValuePairs.TryGetValue(ConnectionStringKeys.UserIdKey, out userId); + KeyValuePairs.TryGetValue(ConnectionStringKeys.PasswordKey, out password); + KeyValuePairs.TryGetValue(ConnectionStringKeys.ServicePrincipalSecretKey, out spnSecret); + KeyValuePairs.TryGetValue(ConnectionStringKeys.TenantIdKey, out aadTenantId); + + //ClientId was provided and servicePrincipal was empty, we want ServicePrincipal to be initialized + //At some point we will deprecate ClientId keyName + if (!string.IsNullOrEmpty(clientId) && (string.IsNullOrEmpty(spn))) + { + KeyValuePairs[ConnectionStringKeys.ServicePrincipalKey] = clientId; + } + + //Set the value of PasswordKey to ServicePrincipalSecret ONLY if userId is empty + //If UserId is not empty, we are not sure if it's a password for inter active login or ServicePrincipal SecretKey + if (!string.IsNullOrEmpty(password) && (string.IsNullOrEmpty(spnSecret)) && (string.IsNullOrEmpty(userId))) + { + KeyValuePairs[ConnectionStringKeys.ServicePrincipalSecretKey] = password; + } + + //Initialize default value for AADTenent + if (string.IsNullOrEmpty(aadTenantId)) + { + KeyValuePairs[ConnectionStringKeys.TenantIdKey] = DEFAULT_TENANTID; + } + } + + public void Parse(string connString) + { + string parseRegEx = @"(?[^=]+)=(?.+)"; + + if (_parseErrorSb != null) _parseErrorSb.Clear(); + + if (string.IsNullOrEmpty(connString)) + { + ParseErrors = "Empty connection string"; + } + else + { + string[] pairs = connString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + if (pairs == null) ParseErrors = string.Format("'{0}' unable to parse string", connString); + + //TODO: Shall we clear keyValue dictionary? + //What if parsed gets called on the same instance multiple times + //the connectionString is either malformed/invalid + //For now clearing keyValue dictionary, we assume the caller wants to parse new connection string + //and wants to discard old values (even if they are valid) + + KeyValuePairs.Clear(clearValuesOnly: true); + foreach (string pair in pairs) + { + Match m = Regex.Match(pair, parseRegEx); + + if (m.Groups.Count > 2) + { + string keyName = m.Groups["KeyName"].Value; + string newValue = m.Groups["KeyValue"].Value; + + if (KeyValuePairs.ContainsKey(keyName)) + { + string existingValue = KeyValuePairs[keyName]; + // Replace if the existing value do not match. + // We allow existing key values to be overwritten (this is especially true for endpoints) + if (!existingValue.Equals(newValue, StringComparison.OrdinalIgnoreCase)) + { + KeyValuePairs[keyName] = newValue; + } + } + else + { + KeyValuePairs[keyName] = newValue; + } + } + else + { + ParseErrors = string.Format("Incorrect '{0}' keyValue pair format", pair); + } + } + + //Adjust key-value pairs and normalize values across multiple keys + //We need to do this here because Connection string can be parsed multiple time within same instance + NormalizeKeyValuePairs(); + } + } + + internal bool HasNonEmptyValue(string connStrKey) + { + KeyValuePairs.TryGetValue(connStrKey, out string keyValue); + + if (string.IsNullOrEmpty(keyValue)) + return false; + + return true; + } + + internal string GetValue(string keyName) + { + return KeyValuePairs[keyName]; + } + + public T GetValue(string keyName) + { + T returnValue = default; + try + { + string keyValue = GetValue(keyName); + returnValue = (T)Convert.ChangeType(keyValue, typeof(T)); + } + catch { } + + return returnValue; + } + + public override string ToString() + { + return _connString; + } + } +} diff --git a/tools/TestFx/ConnectionStringKeys.cs b/tools/TestFx/ConnectionStringKeys.cs new file mode 100644 index 000000000000..04000ffde8c1 --- /dev/null +++ b/tools/TestFx/ConnectionStringKeys.cs @@ -0,0 +1,150 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +namespace Microsoft.Azure.Commands.TestFx +{ + public class ConnectionStringKeys + { + public const string TestCSMOrgIdConnectionStringKey = "TEST_CSM_ORGID_AUTHENTICATION"; + + public const string AZURE_TEST_MODE_ENVKEY = "AZURE_TEST_MODE"; + + /// + /// Environment name + /// + public const string EnvironmentKey = "Environment"; + + /// + /// The key inside the connection string for the management certificate + /// + public const string ManagementCertificateKey = "ManagementCertificate"; + + /// + /// The key inside the connection string for the subscription identifier + /// + public const string SubscriptionIdKey = "SubscriptionId"; + + /// + /// If a tenant other than common is to be used with the subscription, specifies the tenant + /// + public const string TenantIdKey = "TenantId"; + + /// + /// HttpRecorderMode + /// + public const string HttpRecorderModeKey = "HttpRecorderMode"; + + /// + /// The key inside the connection string for a Microsoft ID (OrgId or LiveId) + /// + public const string UserIdKey = "UserId"; + + /// + /// The key inside the connection string for a user password matching the Microsoft ID + /// + public const string PasswordKey = "Password"; + + /// + /// Service principal key + /// + public const string ServicePrincipalKey = "ServicePrincipal"; + + /// + /// ServicePrincipal Secret Key + /// + public const string ServicePrincipalSecretKey = "ServicePrincipalSecret"; + + /// + /// Resource Management endpoint + /// + public const string ResourceManagementUriKey = "ResourceManagementUri"; + + /// + /// Service Management endpoint + /// + public const string ServiceManagementUriKey = "ServiceManagementUri"; + + /// + /// The client ID to use when authenticating with AAD + /// + public const string AADClientIdKey = "AADClientId"; + + /// + /// A raw JWT token for AAD authentication + /// + public const string RawTokenKey = "VidaiTestFxToken"; + + /// + /// A raw JWT token for Graph authentication + /// + public const string RawGraphTokenKey = "RawGraphToken"; + + /// + /// AAD token Audience Uri + /// + public const string AADTokenAudienceUriKey = "AADTokenAudienceUri"; + + /// + /// Graph token Audience Uri + /// + public const string GraphTokenAudienceUriKey = "GraphTokenAudienceUri"; + + /// + /// The key inside the connection string for the base management URI + /// + public const string BaseUriKey = "BaseUri"; + + /// + /// Endpoint to use for AAD authentication + /// + public const string AADAuthUriKey = "AADAuthUri"; //Most probably ActiveDirectoryAuthority + + /// + /// The key inside the connection string for AD Graph URI + /// + public const string GraphUriKey = "GraphUri"; + + /// + /// The key inside the connection string for AD Gallery URI + /// + public const string GalleryUriKey = "GalleryUri"; + + /// + /// The key inside the connection string for the Ibiza Portal URI + /// + public const string IbizaPortalUriKey = "IbizaPortalUri"; + + /// + /// The key inside the connection string for the RDFE Portal URI + /// + public const string RdfePortalUriKey = "RdfePortalUri"; + + /// + /// The key inside the connection string for the DataLake FileSystem URI suffix + /// + public const string DataLakeStoreServiceUriKey = "DataLakeStoreServiceUri"; + + /// + /// The key inside the connection string for the Kona Catalog URI + /// + public const string DataLakeAnalyticsJobAndCatalogServiceUriKey = "DataLakeAnalyticsJobAndCatalogServiceUri"; + + /// + /// Publishsettings endpoint + /// + public const string PublishSettingsFileUriKey = "PublishSettingsFileUri"; + + public const string OptimizeRecordedFileKey = "OptimizeRecordedFile"; + } +} diff --git a/tools/TestFx/DelegatingHandlers/HttpMockServer.cs b/tools/TestFx/DelegatingHandlers/HttpMockServer.cs new file mode 100644 index 000000000000..b530de01c4c4 --- /dev/null +++ b/tools/TestFx/DelegatingHandlers/HttpMockServer.cs @@ -0,0 +1,319 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using Microsoft.Azure.Commands.TestFx.Recorder; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Test.HttpRecorder +{ + public class HttpMockServer : DelegatingHandler + { + private const string TEST_MODE_HEADER = "azSdkTestPlayBackMode"; + private static AssetNames _assetNames; + private static Records _records; + private static List _servers; + private static bool _initialized; + private static readonly Random _randomGenerator = new Random(); + + public static string CallerIdentity { get; set; } + public static string TestIdentity { get; set; } + public static HttpRecorderMode Mode { get; set; } + public static IRecordMatcher Matcher { get; set; } + public static string RecordsDirectory { get; set; } + public static Dictionary Variables { get; private set; } + public static FileSystemUtils FileSystemUtilsObject { get; set; } + + private HttpMockServer() + { + } + + public static void Initialize(Type callerIdentity, string testIdentity) + { + Initialize(callerIdentity, testIdentity, GetCurrentMode()); + } + + public static void Initialize(string callerIdentity, string testIdentity) + { + Initialize(callerIdentity, testIdentity, GetCurrentMode()); + } + + public static void Initialize(Type callerIdentity, string testIdentity, HttpRecorderMode mode) + { + Initialize(callerIdentity.Name, testIdentity, mode); + } + + public static void Initialize(string callerIdentity, string testIdentity, HttpRecorderMode mode) + { + _servers = new List(); + _assetNames = new AssetNames(); + _records = new Records(Matcher); + + CallerIdentity = callerIdentity; + TestIdentity = testIdentity; + Mode = mode; + Variables = new Dictionary(); + + if (Mode == HttpRecorderMode.Playback) + { + var recordDir = Path.Combine(RecordsDirectory, CallerIdentity); + var fileName = Path.GetFullPath(Path.Combine(recordDir, testIdentity.Replace(".json", "") + ".json")); + if (!FileSystemUtilsObject.DirectoryExists(recordDir) || !FileSystemUtilsObject.FileExists(fileName)) + { + throw new ArgumentException($"Unable to find recorded mock file '{fileName}'.", "callerIdentity"); + } + else + { + RecordEntryPack pack = RecordEntryPack.Deserialize(fileName); + lock (_records) + { + pack.Entries.ForEach(p => _records.Enqueue(p)); + } + foreach (var func in pack.Names.Keys) + { + pack.Names[func].ForEach(n => _assetNames.Enqueue(func, n)); + } + if (pack.Variables != null) + { + Variables = pack.Variables; + } + } + } + + _initialized = true; + } + + public static HttpMockServer CreateInstance() + { + if (!_initialized) + { + throw new InvalidOperationException("HttpMockServer has not been initialized yet. Use HttpMockServer.Initialize() method to initialize the HttpMockServer."); + } + HttpMockServer server = new HttpMockServer(); + _servers.Add(server); + return server; + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (Mode == HttpRecorderMode.Playback) + { + // Will throw KeyNotFoundException if the request is not recorded + lock (_records) + { + var key = Matcher.GetMatchingKey(request); + var queue = _records[key]; + if (!queue.Any()) + { + throw new InvalidOperationException($"Queue empty for request {RecorderUtilities.DecodeBase64AsUri(key)}"); + } + + HttpResponseMessage result = queue.Dequeue().GetResponse(); + result = AddTestModeHeaders(result); + result.RequestMessage = request; + return Task.FromResult(result); + } + } + else + { + lock (this) + { + return base.SendAsync(request, cancellationToken).ContinueWith(response => + { + HttpResponseMessage result = response.Result; + if (Mode == HttpRecorderMode.Record) + { + lock (_records) + { + _records.Enqueue(new RecordEntry(result)); + } + } + + return result; + }); + } + } + } + + private HttpResponseMessage AddTestModeHeaders(HttpResponseMessage response) + { + if (response != null) + { + response?.Headers?.Add(TEST_MODE_HEADER, "true"); + } + + return response; + } + + public static string GetAssetName(string testName, string prefix) + { + if (Mode == HttpRecorderMode.Playback) + return _assetNames[testName].Dequeue(); + + string generated = prefix + _randomGenerator.Next(9999); + + if (Mode == HttpRecorderMode.Record) + { + if (_assetNames.ContainsKey(testName)) + { + while (_assetNames[testName].Any(n => n.Equals(generated))) + { + generated = prefix + _randomGenerator.Next(9999); + } + } + _assetNames.Enqueue(testName, generated); + } + + return generated; + } + + /// + /// Gets the asset unique identifier. This is used to store the GUID in the recording so it can be easily retrieved. + /// This behaves the same as name generation, but if useful if the client is required to generate Guids for the service. + /// + /// Name of the test. + /// + public static Guid GetAssetGuid(string testName) + { + if (Mode == HttpRecorderMode.Playback) + return new Guid(_assetNames[testName].Dequeue()); + + string generated = Guid.NewGuid().ToString(); + + if (Mode == HttpRecorderMode.Record) + { + if (_assetNames.ContainsKey(testName)) + { + // this should never happen, but just in case. + while (_assetNames[testName].Any(n => n.Equals(generated))) + { + generated = Guid.NewGuid().ToString(); + } + } + _assetNames.Enqueue(testName, generated); + } + + return new Guid(generated); + } + + /// + /// Returns stored variable or variableValue if variableName is not found. + /// + /// Variable name + /// Variable value to be preserved in recording mode. + /// + public static string GetVariable(string variableName, string variableValue) + { + if (Mode == HttpRecorderMode.Record) + { + Variables[variableName] = variableValue; + return variableValue; + } + else + { + if (Variables.ContainsKey(variableName)) + return Variables[variableName]; + + return variableValue; + } + } + + public void InjectRecordEntry(RecordEntry record) + { + if (Mode == HttpRecorderMode.Playback) + { + lock (_records) + { + _records.Enqueue(record); + } + } + } + + public static string Flush(string outputPath = null) + { + string fileName = string.Empty; + if (Mode == HttpRecorderMode.Record && _records.Count > 0) + { + RecordEntryPack pack = new RecordEntryPack(); + string perfImpactFileName = string.Empty; + string fileDirectory = Path.Combine(outputPath ?? RecordsDirectory, CallerIdentity); + RecorderUtilities.EnsureDirectoryExists(fileDirectory); + + lock (_records) + { + foreach (RecordEntry recordEntry in _records.GetAllEntities()) + { + recordEntry.RequestHeaders.Remove("Authorization"); + recordEntry.RequestUri = new Uri(recordEntry.RequestUri).PathAndQuery; + pack.Entries.Add(recordEntry); + } + } + + fileName = Path.Combine(fileDirectory, (TestIdentity ?? "record") + ".json"); + pack.Variables = Variables; + pack.Names = _assetNames.Names; + + pack.Serialize(fileName); + } + + _servers.ForEach(s => s.Dispose()); + + return fileName; + } + + public static HttpRecorderMode GetCurrentMode() + { + HttpRecorderMode mode; + string input = FileSystemUtilsObject?.GetEnvironmentVariable(ConnectionStringKeys.AZURE_TEST_MODE_ENVKEY); + + if (string.IsNullOrEmpty(input)) + { + mode = HttpRecorderMode.Playback; + } + else + { + mode = (HttpRecorderMode)Enum.Parse(typeof(HttpRecorderMode), input, true); + } + + return mode; + } + } + + public enum HttpRecorderMode + { + /// + /// The mock server does not do anything. + /// + None, + + /// + /// In this mode the mock server watches the out-going requests and records + /// their corresponding responses. + /// + Record, + + /// + /// The playback mode should always be after a successful record session. + /// The mock server matches the given requests and return their stored + /// corresponding responses. + /// + Playback + } +} diff --git a/tools/TestFx/DelegatingHandlers/ResourceCleanerDelegatingHandler.cs b/tools/TestFx/DelegatingHandlers/ResourceCleanerDelegatingHandler.cs new file mode 100644 index 000000000000..15b2b94b4215 --- /dev/null +++ b/tools/TestFx/DelegatingHandlers/ResourceCleanerDelegatingHandler.cs @@ -0,0 +1,68 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Rest; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Net.Http; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.TestFx.DelegatingHandlers +{ + public class ResourceCleanerDelegatingHandler : DelegatingHandler + { + private readonly Regex _resourceGroupPattern = new Regex(@"/subscriptions/[^/]+/resourcegroups/([^?]+)\?api-version"); + private readonly HashSet _resourceGroupsCreated = new HashSet(); + private readonly TokenCredentials _tokenCredentials; + + public ResourceCleanerDelegatingHandler(TokenCredentials tokenCredentials) + { + _tokenCredentials = tokenCredentials; + } + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (_resourceGroupPattern.IsMatch(request.RequestUri.AbsoluteUri) && request.Method == HttpMethod.Put) + { + _resourceGroupsCreated.Add(request.RequestUri.AbsoluteUri); + } + + return base.SendAsync(request, cancellationToken); + } + + public async Task DeleteResourceGroups() + { + HttpClient httpClient = new HttpClient(); + foreach (var resourceGroupUri in _resourceGroupsCreated) + { + HttpRequestMessage httpRequest = new HttpRequestMessage + { + Method = new HttpMethod("DELETE"), + RequestUri = new Uri(resourceGroupUri) + }; + + _tokenCredentials.ProcessHttpRequestAsync(httpRequest, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); + + HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest).ConfigureAwait(false); + string groupName = _resourceGroupPattern.Match(resourceGroupUri).Groups[1].Value; + string message = FormattableString.Invariant($"Started deletion of resource group '{groupName}'. Server responded with status code {httpResponse.StatusCode}."); + Console.WriteLine(message); + Debug.WriteLine(message); + } + } + } +} diff --git a/tools/TestFx/DelegatingHandlers/RetryAfterDelegatingHandler.cs b/tools/TestFx/DelegatingHandlers/RetryAfterDelegatingHandler.cs new file mode 100644 index 000000000000..d99dbf1014b2 --- /dev/null +++ b/tools/TestFx/DelegatingHandlers/RetryAfterDelegatingHandler.cs @@ -0,0 +1,117 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.TestFx.DelegatingHandlers +{ + public class RetryAfterDelegatingHandler : DelegatingHandler + { + public int MaxRetries { get; set; } = int.MaxValue; + + public RetryAfterDelegatingHandler() + { + } + + public RetryAfterDelegatingHandler(DelegatingHandler innerHandler) + : this((HttpMessageHandler)innerHandler) + { + } + + public RetryAfterDelegatingHandler(HttpMessageHandler innerHandler) + : base(innerHandler) + { + } + + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + int attempts = 0; + HttpResponseMessage previousResponseMessage = null; + do + { + HttpResponseMessage response = null; + + try + { + attempts++; + response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + + // if they send back a 429 and there is a retry-after header + if (attempts < MaxRetries && + response.StatusCode == (HttpStatusCode)429 && + response.Headers.Contains("Retry-After")) + { + try + { + // Read back the response message content so it does not go away as this response could be + // used if retries continue to fail. + // NOTE: If the content is not read and this message is returned later, an IO Exception will end up + // happening indicating that request has been aborted. + if (response.Content != null) + { + await response.Content.ReadAsStringAsync().ConfigureAwait(false); + } + + var oldResponse = previousResponseMessage; + previousResponseMessage = response; + oldResponse?.Dispose(); + } + catch + { + // We can end up getting errors reading the content of the message if the connection was closed. + // These errors will be ignored and the previous response will continue to be used. + if (previousResponseMessage != null) + { + response = previousResponseMessage; + } + } + + try + { + // and we get a number of seconds from the header + string retryValue = response.Headers.GetValues("Retry-After").FirstOrDefault(); + var retryAfter = int.Parse(retryValue, CultureInfo.InvariantCulture); + + // wait for that duration + await Task.Delay(TimeSpan.FromSeconds(retryAfter), cancellationToken).ConfigureAwait(false); + + // and try again + continue; + } + catch + { + // if something throws while trying to get the retry-after + // we're just going to suppress it. let the response go + // back to the consumer. + } + } + } + catch (TaskCanceledException) when (previousResponseMessage != null) + { + // We can get Task Canceled Exceptions while calling the base.SendAsync(...) and + // we do not want to let these bubble out when we have a previous response message to return. + } + + // if we haven't hit continue, then return the response up the stream + return response ?? previousResponseMessage; + } while (true); + } + } +} diff --git a/tools/TestFx/DelegatingHandlers/RetryDelegatingHandler.cs b/tools/TestFx/DelegatingHandlers/RetryDelegatingHandler.cs new file mode 100644 index 000000000000..98f65a4ae9b4 --- /dev/null +++ b/tools/TestFx/DelegatingHandlers/RetryDelegatingHandler.cs @@ -0,0 +1,137 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Common.Properties; +using Microsoft.Rest.TransientFaultHandling; +using System; +using System.Globalization; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.TestFx.DelegatingHandlers +{ + internal class RetryDelegatingHandler : DelegatingHandler + { + private const int DefaultNumberOfAttempts = 3; + private readonly TimeSpan DefaultBackoffDelta = new TimeSpan(0, 0, 10); + private readonly TimeSpan DefaultMaxBackoff = new TimeSpan(0, 0, 10); + private readonly TimeSpan DefaultMinBackoff = new TimeSpan(0, 0, 1); + + public RetryPolicy RetryPolicy { get; set; } + + public RetryDelegatingHandler() : base() + { + Init(); + } + + public RetryDelegatingHandler(DelegatingHandler innerHandler) + : this((HttpMessageHandler)innerHandler) + { + } + + public RetryDelegatingHandler(HttpMessageHandler innerHandler) + : base(innerHandler) + { + Init(); + } + + public RetryDelegatingHandler(RetryPolicy retryPolicy, HttpMessageHandler innerHandler) + : this(innerHandler) + { + RetryPolicy = retryPolicy ?? throw new ArgumentNullException("retryPolicy"); + } + + private void Init() + { + var retryStrategy = new ExponentialBackoffRetryStrategy( + DefaultNumberOfAttempts, + DefaultMinBackoff, + DefaultMaxBackoff, + DefaultBackoffDelta); + + RetryPolicy = new RetryPolicy(retryStrategy); + } + + /// + /// Get delegate count associated with the event + /// + public int EventCallbackCount => this.RetryPolicy.EventCallbackCount; + + /// + /// Sends an HTTP request to the inner handler to send to the server as an asynchronous + /// operation. Retries request if needed based on Retry Policy. + /// + /// The HTTP request message to send to the server. + /// A cancellation token to cancel operation. + /// Returns System.Threading.Tasks.Task<TResult>. The + /// task object representing the asynchronous operation. + protected override async Task SendAsync(HttpRequestMessage request, + CancellationToken cancellationToken) + { + HttpResponseMessage responseMessage = null; + HttpResponseMessage lastErrorResponseMessage = null; + try + { + await RetryPolicy.ExecuteAsync(async () => + { + responseMessage = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); + + if (!responseMessage.IsSuccessStatusCode) + { + try + { + // Save off the response message and read back its content so it does not go away as this + // response will be used if retries continue to fail. + // NOTE: If the content is not read and this message is returned later, an IO Exception will end up + // happening indicating that the stream has been aborted. + if (responseMessage.Content != null) + { + await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); + } + + var oldResponse = lastErrorResponseMessage; + lastErrorResponseMessage = responseMessage; + oldResponse?.Dispose(); + } + catch + { + // We can end up getting errors reading the content of the message if the connection was closed. + // These errors will be ignored and the previous last error response will continue to be used. + if (lastErrorResponseMessage != null) + { + responseMessage = lastErrorResponseMessage; + } + } + + throw new HttpRequestWithStatusException(string.Format( + CultureInfo.InvariantCulture, + Resources.ResponseStatusCodeError, + (int)responseMessage.StatusCode, + responseMessage.StatusCode)) + { StatusCode = responseMessage.StatusCode }; + } + + return responseMessage; + }, cancellationToken).ConfigureAwait(false); + + return responseMessage; + } + catch (Exception) when (responseMessage != null || lastErrorResponseMessage != null) + { + return responseMessage ?? lastErrorResponseMessage; + } + } + } +} diff --git a/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs b/tools/TestFx/EnvironmentSetupHelper.cs similarity index 69% rename from tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs rename to tools/TestFx/EnvironmentSetupHelper.cs index 4c96f82a8ea6..8fb5806243fb 100644 --- a/tools/ScenarioTest.ResourceManager/EnvironmentSetupHelper.cs +++ b/tools/TestFx/EnvironmentSetupHelper.cs @@ -16,14 +16,13 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.ScenarioTest; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.Azure.ServiceManagement.Common.Models; -using Microsoft.Azure.Test; using Microsoft.Azure.Test.HttpRecorder; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using Microsoft.WindowsAzure.Commands.Common; -using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using Microsoft.WindowsAzure.Commands.Utilities.Common; using System; -using System.Reflection; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; @@ -31,18 +30,18 @@ using System.Linq; using System.Management.Automation; using System.Net.Http; +using System.Reflection; using System.Runtime.InteropServices; -using System.Threading; using System.Text; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using System.Threading; -namespace Microsoft.WindowsAzure.Commands.ScenarioTest +namespace Microsoft.Azure.Commands.TestFx { public class EnvironmentSetupHelper { - private static string testEnvironmentName = "__test-environment"; + private const string TestEnvironmentName = "__test-environment"; - private static string testSubscriptionName = "__test-subscriptions"; + private const string TestSubscriptionName = "__test-subscriptions"; private AzureSubscription testSubscription; @@ -51,20 +50,24 @@ public class EnvironmentSetupHelper private static string PackageDirectoryFromCommon { get; } = GetConfigDirectory(); public static string PackageDirectory { get; } = GetConfigDirectory(); + public static string StackDirectory { get; } = GetConfigDirectory("Stack"); public static string RmDirectory { get; } = GetRMModuleDirectory(); + public static string StackRmDirectory { get; } = GetRMModuleDirectory("Stack"); public static string StorageDirectory { get; } = GetStorageDirectory(); + public static string StackStorageDirectory { get; } = GetStorageDirectory("Stack"); protected List modules; public XunitTracingInterceptor TracingInterceptor { get; set; } + public EnvironmentSetupHelper() { - var module = GetModuleManifest(RmDirectory, "AzureRM.Accounts"); + var module = GetModuleManifest(RmDirectory, "Az.Accounts"); if (string.IsNullOrWhiteSpace(module)) { throw new InvalidOperationException("Could not find Accounts module"); @@ -72,37 +75,37 @@ public EnvironmentSetupHelper() LogIfNotNull($"Accounts Module path: {module}"); RMProfileModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.Resources"); + module = GetModuleManifest(RmDirectory, "Az.Resources"); LogIfNotNull($"Resources Module path: {module}"); RMResourceModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.Insights"); + module = GetModuleManifest(RmDirectory, "Az.Insights"); LogIfNotNull($"Insights Module path: {module}"); RMInsightsModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.Storage"); + module = GetModuleManifest(RmDirectory, "Az.Storage"); LogIfNotNull($"Storage Management Module path: {module}"); RMStorageModule = module; module = GetModuleManifest(StorageDirectory, "Azure.Storage"); LogIfNotNull($"Storage Data Plane Module path: {module}"); RMStorageDataPlaneModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.OperationalInsights"); + module = GetModuleManifest(RmDirectory, "Az.OperationalInsights"); LogIfNotNull($"Storage Data Plane Module path: {module}"); RMOperationalInsightsModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.Network"); + module = GetModuleManifest(RmDirectory, "Az.Network"); LogIfNotNull($"Network Module path: {module}"); RMNetworkModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.EventHub"); + module = GetModuleManifest(RmDirectory, "Az.EventHub"); LogIfNotNull($"EventHub Module path: {module}"); RMEventHubModule = module; - module = GetModuleManifest(RmDirectory, "AzureRM.Monitor"); + module = GetModuleManifest(RmDirectory, "Az.Monitor"); LogIfNotNull($"Monitor Module path: {module}"); RMMonitorModule = module; - module = GetModuleManifest(StackRmDirectory, "AzureRM.Accounts"); + module = GetModuleManifest(StackRmDirectory, "Az.Accounts"); LogIfNotNull($"Stack Accounts Module path: {module}"); StackRMProfileModule = module; - module = GetModuleManifest(StackRmDirectory, "AzureRM.Resources"); + module = GetModuleManifest(StackRmDirectory, "Az.Resources"); LogIfNotNull($"Stack Resources Module path: {module}"); StackRMResourceModule = module; - module = GetModuleManifest(StackRmDirectory, "AzureRM.Storage"); + module = GetModuleManifest(StackRmDirectory, "Az.Storage"); LogIfNotNull($"Stack Storage Management Plane Module path: {module}"); StackRMStorageModule = module; module = GetModuleManifest(StackStorageDirectory, "Azure.Storage"); @@ -157,12 +160,10 @@ public EnvironmentSetupHelper() public string RMMonitorModule { get; private set; } - //TODO: clarify (data plane should not be under ARM folder) public string RMStorageDataPlaneModule { get; private set; } public string RMNetworkModule { get; private set; } - public string StackRMProfileModule { get; private set; } public string StackRMResourceModule { get; private set; } @@ -175,7 +176,7 @@ public EnvironmentSetupHelper() private void LogIfNotNull(string message) { - if (this.TracingInterceptor != null) + if (TracingInterceptor != null) { TracingInterceptor.Information($"[EnvironmentSetupHelper]: {message}"); } @@ -280,23 +281,14 @@ public string GetStackRMModulePath(string moduleName) return GetModuleManifest(StackRmDirectory, moduleDirectory); } - - /// - /// Loads DummyManagementClientHelper with clients and throws exception if any client is missing. - /// - /// - public void SetupManagementClients(params object[] initializedManagementClients) + public void SetupManagementClients(MockContext context, params object[] initializedManagementClients) { - AzureSession.Instance.ClientFactory = new MockClientFactory(initializedManagementClients); + AzureSession.Instance.ClientFactory = new MockClientFactory(context, initializedManagementClients); } - /// - /// Loads DummyManagementClientHelper with clients and sets it up to create missing clients dynamically. - /// - /// - public void SetupSomeOfManagementClients(params object[] initializedManagementClients) + public void SetupSomeOfManagementClients(MockContext context, params object[] initializedManagementClients) { - AzureSession.Instance.ClientFactory = new MockClientFactory(initializedManagementClients, false); + AzureSession.Instance.ClientFactory = new MockClientFactory(context, initializedManagementClients); } public void SetupEnvironment(AzureModule mode) @@ -307,101 +299,96 @@ public void SetupEnvironment(AzureModule mode) public void SetEnvironmentVariableFromCredentialFile() { var filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".azure", "testcredentials.json"); - Dictionary credentials; + Dictionary testSettings; using (StreamReader r = new StreamReader(filePath)) { string json = r.ReadToEnd(); - credentials = JsonUtilities.DeserializeJson(json); + testSettings = JsonUtilities.DeserializeJson(json); } - if (Environment.GetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION") == null) + if (Environment.GetEnvironmentVariable(ConnectionStringKeys.TestCSMOrgIdConnectionStringKey) == null) { StringBuilder formattedConnectionString = new StringBuilder(); - formattedConnectionString.AppendFormat("SubscriptionId={0};HttpRecorderMode={1};Environment={2}", credentials["SubscriptionId"], credentials["HttpRecorderMode"], credentials["Environment"]); - - if (credentials.ContainsKey("UserId")) - { - formattedConnectionString.AppendFormat(";UserId={0}", credentials["UserId"]); - } + formattedConnectionString.Append($"Environment={testSettings["Environment"]};SubscriptionId={testSettings["SubscriptionId"]};TenantId={testSettings["TenantId"]};HttpRecorderMode={testSettings["HttpRecorderMode"]};"); - if (credentials.ContainsKey("ServicePrincipal")) + if (testSettings.ContainsKey("UserId")) { - formattedConnectionString.AppendFormat(";ServicePrincipal={0}", credentials["ServicePrincipal"]); - formattedConnectionString.AppendFormat(";ServicePrincipalSecret={0}", credentials["ServicePrincipalSecret"]); + formattedConnectionString.Append($"UserId={testSettings["UserId"]};"); } - if (credentials.ContainsKey("TenantId")) + if (testSettings.ContainsKey("ServicePrincipal")) { - formattedConnectionString.AppendFormat(";AADTenant={0}", credentials["TenantId"]); + formattedConnectionString.Append($"ServicePrincipal={testSettings["ServicePrincipal"]};"); + formattedConnectionString.Append($"ServicePrincipalSecret={testSettings["ServicePrincipalSecret"]};"); } - if (credentials.ContainsKey("ResourceManagementUri")) + if (testSettings.ContainsKey("ResourceManagementUri")) { - formattedConnectionString.AppendFormat(";ResourceManagementUri={0}", credentials["ResourceManagementUri"]); + formattedConnectionString.Append($"ResourceManagementUri={testSettings["ResourceManagementUri"]};"); } - if (credentials.ContainsKey("GraphUri")) + if (testSettings.ContainsKey("ServiceManagementUri")) { - formattedConnectionString.AppendFormat(";GraphUri={0}", credentials["GraphUri"]); + formattedConnectionString.Append($"ServiceManagementUri={testSettings["ServiceManagementUri"]};"); } - if (credentials.ContainsKey("AADAuthUri")) + if (testSettings.ContainsKey("AADAuthUri")) { - formattedConnectionString.AppendFormat(";AADAuthUri={0}", credentials["AADAuthUri"]); + formattedConnectionString.Append($"AADAuthUri={testSettings["AADAuthUri"]};"); } - if (credentials.ContainsKey("AADTokenAudienceUri")) + if (testSettings.ContainsKey("GraphUri")) { - formattedConnectionString.AppendFormat(";AADTokenAudienceUri={0}", credentials["AADTokenAudienceUri"]); + formattedConnectionString.Append($"GraphUri={testSettings["GraphUri"]};"); } - if (credentials.ContainsKey("GraphTokenAudienceUri")) + if (testSettings.ContainsKey("AADTokenAudienceUri")) { - formattedConnectionString.AppendFormat(";GraphTokenAudienceUri={0}", credentials["GraphTokenAudienceUri"]); + formattedConnectionString.Append($"AADTokenAudienceUri={testSettings["AADTokenAudienceUri"]};"); } - if (credentials.ContainsKey("IbizaPortalUri")) + if (testSettings.ContainsKey($"GraphTokenAudienceUri")) { - formattedConnectionString.AppendFormat(";IbizaPortalUri={0}", credentials["IbizaPortalUri"]); + formattedConnectionString.Append($"GraphTokenAudienceUri={testSettings["GraphTokenAudienceUri"]};"); } - if (credentials.ContainsKey("ServiceManagementUri")) + if (testSettings.ContainsKey("IbizaPortalUri")) { - formattedConnectionString.AppendFormat(";ServiceManagementUri={0}", credentials["ServiceManagementUri"]); + formattedConnectionString.Append($"IbizaPortalUri={testSettings["IbizaPortalUri"]};"); } - if (credentials.ContainsKey("RdfePortalUri")) + if (testSettings.ContainsKey("RdfePortalUri")) { - formattedConnectionString.AppendFormat(";RdfePortalUri={0}", credentials["RdfePortalUri"]); + formattedConnectionString.Append($"RdfePortalUri={testSettings["RdfePortalUri"]};"); } - if (credentials.ContainsKey("GalleryUri")) + if (testSettings.ContainsKey("GalleryUri")) { - formattedConnectionString.AppendFormat(";GalleryUri={0}", credentials["GalleryUri"]); + formattedConnectionString.Append($"GalleryUri={testSettings["GalleryUri"]};"); } - if (credentials.ContainsKey("DataLakeStoreServiceUri")) + if (testSettings.ContainsKey("DataLakeStoreServiceUri")) { - formattedConnectionString.AppendFormat(";DataLakeStoreServiceUri={0}", credentials["DataLakeStoreServiceUri"]); + formattedConnectionString.Append($"DataLakeStoreServiceUri={testSettings["DataLakeStoreServiceUri"]};"); } - if (credentials.ContainsKey("DataLakeAnalyticsJobAndCatalogServiceUri")) + if (testSettings.ContainsKey("DataLakeAnalyticsJobAndCatalogServiceUri")) { - formattedConnectionString.AppendFormat(";DataLakeAnalyticsJobAndCatalogServiceUri={0}", credentials["DataLakeAnalyticsJobAndCatalogServiceUri"]); + formattedConnectionString.Append($"DataLakeAnalyticsJobAndCatalogServiceUri={testSettings["DataLakeAnalyticsJobAndCatalogServiceUri"]};"); } - Environment.SetEnvironmentVariable("TEST_CSM_ORGID_AUTHENTICATION", formattedConnectionString.ToString()); + Environment.SetEnvironmentVariable(ConnectionStringKeys.TestCSMOrgIdConnectionStringKey, formattedConnectionString.ToString()); } - if (Environment.GetEnvironmentVariable("AZURE_TEST_MODE") == null) + if (Environment.GetEnvironmentVariable(ConnectionStringKeys.AZURE_TEST_MODE_ENVKEY) == null) { - Environment.SetEnvironmentVariable("AZURE_TEST_MODE", credentials["HttpRecorderMode"].ToString()); + Environment.SetEnvironmentVariable(ConnectionStringKeys.AZURE_TEST_MODE_ENVKEY, testSettings["HttpRecorderMode"].ToString()); } } public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode) { - TestEnvironment currentEnvironment = null; + TestEnvironment currentEnvironment; if (mode == AzureModule.AzureResourceManager) { currentEnvironment = TestEnvironmentFactory.GetTestEnvironment(); @@ -416,8 +403,8 @@ public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode) currentEnvironment.UserName = "fakeuser@microsoft.com"; } - SetAuthenticationFactory(mode, currentEnvironment); - AzureEnvironment environment = new AzureEnvironment { Name = testEnvironmentName }; + SetAuthenticationFactory(currentEnvironment); + AzureEnvironment environment = new AzureEnvironment { Name = TestEnvironmentName }; Debug.Assert(currentEnvironment != null); environment.ActiveDirectoryAuthority = currentEnvironment.Endpoints.AADAuthUri.AbsoluteUri; environment.GalleryUrl = currentEnvironment.Endpoints.GalleryUri.AbsoluteUri; @@ -431,20 +418,20 @@ public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode) environment.AzureKeyVaultServiceEndpointResourceId = AzureEnvironmentConstants.AzureKeyVaultServiceEndpointResourceId; environment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.OperationalInsightsEndpoint, "https://api.loganalytics.io/v1"); environment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.OperationalInsightsEndpointResourceId, "https://api.loganalytics.io"); - if (!AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable.ContainsKey(testEnvironmentName)) + if (!AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable.ContainsKey(TestEnvironmentName)) { - AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable[testEnvironmentName] = environment; + AzureRmProfileProvider.Instance.GetProfile().EnvironmentTable[TestEnvironmentName] = environment; } if (currentEnvironment.SubscriptionId != null) { - testSubscription = new AzureSubscription() + testSubscription = new AzureSubscription { Id = currentEnvironment.SubscriptionId, - Name = testSubscriptionName, + Name = TestSubscriptionName, }; - testSubscription.SetEnvironment(testEnvironmentName); + testSubscription.SetEnvironment(TestEnvironmentName); testSubscription.SetAccount(currentEnvironment.UserName); testSubscription.SetDefault(); testSubscription.SetStorageAccount(Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT")); @@ -457,20 +444,20 @@ public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode) testAccount.SetSubscriptions(currentEnvironment.SubscriptionId); var testTenant = new AzureTenant() { Id = Guid.NewGuid().ToString() }; - if (!string.IsNullOrEmpty(currentEnvironment.Tenant)) + if (!string.IsNullOrEmpty(currentEnvironment.TenantId)) { - if (Guid.TryParse(currentEnvironment.Tenant, out Guid tenant)) + if (Guid.TryParse(currentEnvironment.TenantId, out _)) { - testTenant.Id = currentEnvironment.Tenant; + testTenant.Id = currentEnvironment.TenantId; } } AzureRmProfileProvider.Instance.Profile.DefaultContext = new AzureContext(testSubscription, testAccount, environment, testTenant); } } - private void SetAuthenticationFactory(AzureModule mode, TestEnvironment environment) + private void SetAuthenticationFactory(TestEnvironment environment) { - if(environment.TokenInfo.ContainsKey(TokenAudience.Management)) + if (environment.TokenInfo.ContainsKey(TokenAudience.Management)) { var httpMessage = new HttpRequestMessage(); environment.TokenInfo[TokenAudience.Management] @@ -479,9 +466,7 @@ private void SetAuthenticationFactory(AzureModule mode, TestEnvironment environm .GetAwaiter() .GetResult(); - AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory( - environment.UserName, - httpMessage.Headers.Authorization.Parameter); + AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(environment.UserName, httpMessage.Headers.Authorization.Parameter); } } @@ -542,56 +527,35 @@ public void SetupModules(params string[] modules) public virtual Collection RunPowerShellTest(params string[] scripts) { - // If a test customizes the reecord matcher, use the cutomized version otherwise use the default - // permissive record matcher. - if (HttpMockServer.Matcher == null || HttpMockServer.Matcher.GetType() == typeof(SimpleRecordMatcher)) + using var powershell = System.Management.Automation.PowerShell.Create(RunspaceMode.NewRunspace); + SetupPowerShellModules(powershell); + + Collection output = null; + foreach (var script in scripts) { - var d = new Dictionary - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null}, - {"Microsoft.Compute", null}, - }; - var providersToIgnore = new Dictionary - { - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - }; - HttpMockServer.Matcher = new PermissiveRecordMatcherWithApiExclusion(true, d, providersToIgnore); + TracingInterceptor?.Information(script); + powershell.AddScript(script); } - - using (var powershell = System.Management.Automation.PowerShell.Create(RunspaceMode.NewRunspace)) + try { - SetupPowerShellModules(powershell); - - Collection output = null; - foreach (var script in scripts) + output = powershell.Invoke(); + if (powershell.Streams.Error.Count > 0) { - TracingInterceptor?.Information(script); - powershell.AddScript(script); + throw new RuntimeException($"Test failed due to a non-empty error stream. First error: {PowerShellExtensions.FormatErrorRecord(powershell.Streams.Error[0])}{(powershell.Streams.Error.Count > 0 ? "Check the error stream in the test log for additional errors." : "")}"); } - try - { - output = powershell.Invoke(); - if (powershell.Streams.Error.Count > 0) - { - throw new RuntimeException( - $"Test failed due to a non-empty error stream. First error: {PowerShellExtensions.FormatErrorRecord(powershell.Streams.Error[0])}{(powershell.Streams.Error.Count > 0 ? "Check the error stream in the test log for additional errors." : "")}"); - } - return output; - } - catch (Exception psException) - { - powershell.LogPowerShellException(psException, TracingInterceptor); - powershell.LogPowerShellResults(output, TracingInterceptor); - TracingInterceptor?.Flush(); - throw; - } - finally - { - powershell.Streams.Error.Clear(); - } + return output; + } + catch (Exception psException) + { + powershell.LogPowerShellException(psException, TracingInterceptor); + powershell.LogPowerShellResults(output, TracingInterceptor); + TracingInterceptor?.Flush(); + throw; + } + finally + { + powershell.Streams.Error.Clear(); } } @@ -601,19 +565,18 @@ private void SetupPowerShellModules(System.Management.Automation.PowerShell powe { powershell.AddScript("Set-ExecutionPolicy Unrestricted -Scope Process -ErrorAction Ignore"); } - powershell.AddScript("$error.clear()"); - powershell.AddScript($"Write-Debug \"current directory: {System.AppDomain.CurrentDomain.BaseDirectory}\""); - powershell.AddScript( - $"Write-Debug \"current executing assembly: {Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\""); - powershell.AddScript($"cd \"{System.AppDomain.CurrentDomain.BaseDirectory}\""); + powershell.AddScript("$Error.clear()"); + powershell.AddScript($"Write-Debug \"current directory: {AppDomain.CurrentDomain.BaseDirectory}\""); + powershell.AddScript($"Write-Debug \"current executing assembly: {Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)}\""); + powershell.AddScript($"cd \"{AppDomain.CurrentDomain.BaseDirectory}\""); foreach (var moduleName in modules) { powershell.AddScript($"Import-Module \"{moduleName.AsAbsoluteLocation()}\""); if (moduleName.EndsWith(".psd1")) { - var moduleShortName = moduleName.Split(new string[] { "\\" }, StringSplitOptions.None).Last().Split(new string[] { "/" }, StringSplitOptions.None).Last(); - powershell.AddScript("Enable-AzureRmAlias -Module " + moduleShortName.Substring(0, moduleShortName.Length - 5)); + var moduleShortName = moduleName.Split(new string[] { @"\" }, StringSplitOptions.None).Last().Split(new string[] { @"/" }, StringSplitOptions.None).Last(); + powershell.AddScript("Enable-AzureRmAlias -Module " + moduleShortName[..^5]); if (moduleShortName.Equals("Az.Storage.psd1") && modules.Any(s => s.EndsWith("AzureRM.Storage.ps1"))) { powershell.AddScript("Get-Alias | Where-Object {$_.Name -like '*-AzureRmStorage*'} | ForEach-Object { Remove-Item \"alias:\\$_\" }"); @@ -622,15 +585,13 @@ private void SetupPowerShellModules(System.Management.Automation.PowerShell powe } powershell.AddScript("Disable-AzureRmDataCollection -ErrorAction Ignore"); - powershell.AddScript( - $"set-location \"{System.AppDomain.CurrentDomain.BaseDirectory}\""); - powershell.AddScript($@"$TestOutputRoot='{System.AppDomain.CurrentDomain.BaseDirectory}'"); + powershell.AddScript($"Set-Location \"{AppDomain.CurrentDomain.BaseDirectory}\""); + powershell.AddScript($"$TestOutputRoot='{AppDomain.CurrentDomain.BaseDirectory}'"); powershell.AddScript("$VerbosePreference='Continue'"); powershell.AddScript("$DebugPreference='Continue'"); powershell.AddScript("$ErrorActionPreference='Stop'"); powershell.AddScript("Write-Debug \"AZURE_TEST_MODE = $($env:AZURE_TEST_MODE)\""); powershell.AddScript("Write-Debug \"TEST_HTTPMOCK_OUTPUT = $($env:TEST_HTTPMOCK_OUTPUT)\""); } - } } diff --git a/tools/TestFx/ExtensionMethods.cs b/tools/TestFx/ExtensionMethods.cs new file mode 100644 index 000000000000..ff2cc289c479 --- /dev/null +++ b/tools/TestFx/ExtensionMethods.cs @@ -0,0 +1,114 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Linq; +using System.Reflection; + +namespace Microsoft.Azure.Commands.TestFx +{ + public static class ExtensionMethods + { + public static string GetValueUsingCaseInsensitiveKey(this Dictionary dictionary, string keyName) + { + //string valueForKey; + if (dictionary.TryGetValue(keyName, out string valueForKey)) + return valueForKey; + + if (dictionary.TryGetValue(keyName.ToLower(), out valueForKey)) + return valueForKey; + + return valueForKey; + } + + /// + /// Searches dictionary with key as provided as well as key.ToLower() + /// + /// + /// + /// + public static bool ContainsCaseInsensitiveKey(this Dictionary dictionary, string keyName) + { + if (dictionary.ContainsKey(keyName)) + return true; + + if (dictionary.ContainsKey(keyName.ToLower())) + return true; + + return false; + } + + /// + /// Updates the dictionary first by searching for key as provided then does a second pass for key.ToLower() + /// + /// + /// + /// + public static void UpdateDictionary(this Dictionary dictionary, string keyName, string value) + { + if (dictionary.ContainsKey(keyName)) + { + dictionary[keyName] = value; + } + else if (dictionary.ContainsKey(keyName.ToLower())) + { + dictionary[keyName.ToLower()] = value; + } + } + + /// + /// Allows you to clear only values or key/value both + /// + /// Dictionary that to be cleared + /// True: Clears only values, False: Clear keys and values + public static void Clear(this Dictionary dictionary, bool clearValuesOnly) + { + //TODO: can be implemented for generic dictionary, but currently there is no requirement, else the overload + //will be reflected for the entire solution for any kind of Dictionary, so currently only scoping to Dictionary + if (clearValuesOnly) + { + foreach (string key in dictionary.Keys.ToList()) + { + dictionary[key] = string.Empty; + } + } + else + { + dictionary.Clear(); + } + } + + /// + /// Creates comma seperated string of all TestEnvironmentNames enum values + /// + /// + /// + public static string ListValues(this TestEnvironmentName env) + { + List enumValues = (from ev in typeof(TestEnvironmentName).GetMembers(BindingFlags.Public | BindingFlags.Static) select ev.Name).ToList(); + return string.Join(",", enumValues.Select((item) => item)); + } + + /// + /// Checks if IEnumerable is null or empty + /// + /// + /// + /// + public static bool IsAny(this IEnumerable collection) + { + return collection != null && collection.Any(); + } + } +} diff --git a/tools/TestFx/ITestRunner.cs b/tools/TestFx/ITestRunner.cs index a34259e9832c..54ea173117cd 100644 --- a/tools/TestFx/ITestRunner.cs +++ b/tools/TestFx/ITestRunner.cs @@ -12,6 +12,7 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using System; namespace Microsoft.Azure.Commands.TestFx @@ -19,6 +20,11 @@ namespace Microsoft.Azure.Commands.TestFx public interface ITestRunner { void RunTestScript(params string[] scripts); + + void RunTestScript(Action contextAction, params string[] scripts); + void RunTestScript(Action setUp, Action tearDown, params string[] scripts); + + void RunTestScript(Action setUp, Action contextAction, Action tearDown, params string[] scripts); } } diff --git a/tools/TestFx/ITestRunnerFactory.cs b/tools/TestFx/ITestRunnerFactory.cs index ec4c27517ea0..96b3322e8c7e 100644 --- a/tools/TestFx/ITestRunnerFactory.cs +++ b/tools/TestFx/ITestRunnerFactory.cs @@ -12,25 +12,36 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; using System; using System.Collections.Generic; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.WindowsAzure.Commands.ScenarioTest; namespace Microsoft.Azure.Commands.TestFx { public interface ITestRunnerFactory { - ITestRunner Build(); ITestRunnerFactory WithProjectSubfolderForTests(string folderName); - ITestRunnerFactory WithCommonPsScripts(string[] psScriptList); + ITestRunnerFactory WithNewPsScriptFilename(string psScriptName); - ITestRunnerFactory WithMockContextAction(Action mockContextAction); - ITestRunnerFactory WithExtraRmModules(Func buildModuleList); + + ITestRunnerFactory WithCommonPsScripts(string[] psScriptList); + ITestRunnerFactory WithNewRmModules(Func buildModuleList); - ITestRunnerFactory WithExtraUserAgentsToIgnore(Dictionary userAgentsToIgnore); + + ITestRunnerFactory WithExtraRmModules(Func buildModuleList); + + ITestRunnerFactory WithInitAction(Action initAction); + + ITestRunnerFactory WithMockContextAction(Action mockContextAction); + + ITestRunnerFactory WithCleanupAction(Action cleanupAction); + ITestRunnerFactory WithRecordMatcher(RecordMatcherDelegate recordMatcher); - ITestRunnerFactory WithNewRecordMatcherArguments(Dictionary userAgentsToIgnore, Dictionary resourceProviders); - ITestRunnerFactory WithManagementClients(params Func []initializedManagementClients); + + ITestRunnerFactory WithNewRecordMatcherArguments(Dictionary userAgentsToIgnore, Dictionary resourceProviders, bool ignoreResourceClient = true); + + ITestRunnerFactory WithManagementClients(params Func[] initializedManagementClients); + + ITestRunner Build(); } } diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockAccessToken.cs b/tools/TestFx/Mocks/MockAccessToken.cs similarity index 85% rename from tools/ScenarioTest.ResourceManager/Mocks/MockAccessToken.cs rename to tools/TestFx/Mocks/MockAccessToken.cs index 5ef70e8ebf57..b18837cbabfd 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockAccessToken.cs +++ b/tools/TestFx/Mocks/MockAccessToken.cs @@ -16,28 +16,25 @@ using System; using System.Collections.Generic; -namespace Microsoft.WindowsAzure.Commands.Common.Test.Mocks +namespace Microsoft.Azure.Commands.TestFx.Mocks { public class MockAccessToken : IRenewableToken { - private string _tenantId = String.Empty; - public void AuthorizeRequest(Action authTokenSetter) - { - authTokenSetter("Bearer", AccessToken); - } + public string TenantId { get; set; } - public string AccessToken { get; set; } public string UserId { get; set; } + public string LoginType { get; set; } - public string TenantId - { - get { return _tenantId; } - set { _tenantId = value; } - } + public string AccessToken { get; set; } public DateTimeOffset ExpiresOn { get; set; } + public void AuthorizeRequest(Action authTokenSetter) + { + authTokenSetter("Bearer", AccessToken); + } + public string HomeAccountId => throw new NotImplementedException(); public IDictionary ExtendedProperties => throw new NotImplementedException(); diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockAccessTokenProvider.cs b/tools/TestFx/Mocks/MockAccessTokenProvider.cs similarity index 68% rename from tools/ScenarioTest.ResourceManager/Mocks/MockAccessTokenProvider.cs rename to tools/TestFx/Mocks/MockAccessTokenProvider.cs index c8a7892130c1..fa17a20a85e7 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockAccessTokenProvider.cs +++ b/tools/TestFx/Mocks/MockAccessTokenProvider.cs @@ -13,26 +13,26 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; using System; using System.Security; -namespace Microsoft.WindowsAzure.Commands.Test.Utilities.Common +namespace Microsoft.Azure.Commands.TestFx.Mocks { public class MockAccessTokenProvider : ITokenProvider { - private readonly IAccessToken accessToken; + private readonly IAccessToken _accessToken; - public MockAccessTokenProvider(string token) - : this(token, "user@live.com") - { } + public MockAccessTokenProvider(string token) : this(token, "MockUser") + { + + } public MockAccessTokenProvider(string token, string userId) { - this.accessToken = new MockAccessToken() + _accessToken = new MockAccessToken { AccessToken = token, + LoginType = LoginType.OrgId, UserId = userId }; } @@ -41,23 +41,31 @@ public IAccessToken GetAccessToken( AdalConfiguration config, string promptBehavior, Action promptAction, - string userId, + string userId, SecureString password, string credentialType) { - return this.accessToken; + return _accessToken; } #if !NETSTANDARD - IAccessToken ITokenProvider.GetAccessTokenWithCertificate(AdalConfiguration config, string principalId, string certificateThumbprint, + IAccessToken ITokenProvider.GetAccessTokenWithCertificate( + AdalConfiguration config, + string principalId, + string certificateThumbprint, string credentialType) { return GetAccessTokenWithCertificate(config, principalId, certificateThumbprint, credentialType); } #endif - public IAccessToken GetAccessTokenWithCertificate(AdalConfiguration config, string principalId, string certificateThumbprint, string credentialType) + + public IAccessToken GetAccessTokenWithCertificate( + AdalConfiguration config, + string principalId, + string certificateThumbprint, + string credentialType) { - return this.accessToken; + return _accessToken; } } diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs b/tools/TestFx/Mocks/MockCertificateAuthenticationFactory.cs similarity index 83% rename from tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs rename to tools/TestFx/Mocks/MockCertificateAuthenticationFactory.cs index db57ca108dec..1677af2a621d 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockCertificateAuthenticationFactory.cs +++ b/tools/TestFx/Mocks/MockCertificateAuthenticationFactory.cs @@ -12,15 +12,14 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.Authentication.Models; +using Microsoft.Rest; using System; using System.Security; using System.Security.Cryptography.X509Certificates; -namespace Microsoft.WindowsAzure.Commands.Common.Test.Mocks +namespace Microsoft.Azure.Commands.TestFx.Mocks { public class MockCertificateAuthenticationFactory : IAuthenticationFactory { @@ -78,27 +77,24 @@ public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContex return new CertificateCloudCredentials(context.Subscription.Id.ToString(), Certificate); } - - public Microsoft.Rest.ServiceClientCredentials GetServiceClientCredentials(IAzureContext context) - { - throw new System.NotImplementedException(); - } - - public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context, string targetEndpoint) { return new CertificateCloudCredentials(context.Subscription.Id.ToString(), Certificate); } + public ServiceClientCredentials GetServiceClientCredentials(IAzureContext context) + { + throw new NotImplementedException(); + } - public Rest.ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint) + public ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } - public Rest.ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) + public ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockClientFactory.cs b/tools/TestFx/Mocks/MockClientFactory.cs similarity index 52% rename from tools/ScenarioTest.ResourceManager/Mocks/MockClientFactory.cs rename to tools/TestFx/Mocks/MockClientFactory.cs index 56761d025589..1b99b29433a1 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockClientFactory.cs +++ b/tools/TestFx/Mocks/MockClientFactory.cs @@ -12,20 +12,15 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Hyak.Common; -using Microsoft.Azure; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Factories; using Microsoft.Azure.Commands.Common.Authentication.Models; -using Microsoft.Azure.Test.HttpRecorder; using Microsoft.Rest.Azure; -using Microsoft.WindowsAzure.Commands.ScenarioTest; using Microsoft.WindowsAzure.Commands.Utilities.Common; using System; using System.Collections.Generic; using System.Diagnostics; -using System.IO; using System.Linq; using System.Net; using System.Net.Http; @@ -33,119 +28,78 @@ using System.Reflection; using System.Threading; using System.Threading.Tasks; +using Microsoft.Azure.Commands.TestFx.DelegatingHandlers; +using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using Microsoft.Azure.Test.HttpRecorder; #if NETSTANDARD using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; #endif -namespace Microsoft.WindowsAzure.Commands.Common.Test.Mocks +namespace Microsoft.Azure.Commands.TestFx.Mocks { public class MockClientFactory : IClientFactory { - private readonly bool throwWhenNotAvailable; + private readonly MockContext _mockContext; + + private readonly List _serviceClients; public bool MoqClients { get; set; } - public List ManagementClients { get; private set; } + public HashSet UniqueUserAgents { get; set; } = new HashSet(); + public ProductInfoHeaderValue[] UserAgents => UniqueUserAgents.ToArray(); - public MockClientFactory(IEnumerable clients, bool throwIfClientNotSpecified = true) + public MockClientFactory(MockContext mockContext, IEnumerable serviceClients) { - UniqueUserAgents = new HashSet(); - ManagementClients = clients.ToList(); - throwWhenNotAvailable = throwIfClientNotSpecified; + _mockContext = mockContext; + _serviceClients = serviceClients?.ToList() ?? new List(); } - public TClient CreateClient(IAzureContext context, string endpoint) where TClient : ServiceClient + public void AddUserAgent(string productName) { - Debug.Assert(context != null); + AddUserAgent(productName, ""); + } - SubscriptionCloudCredentials creds = AzureSession.Instance.AuthenticationFactory - .GetSubscriptionCloudCredentials( - context, - AzureEnvironment.Endpoint.ResourceManager); - TClient client = CreateCustomClient(creds, context.Environment.GetEndpointAsUri(endpoint)); + public void AddUserAgent(string productName, string productVersion) + { + if (string.IsNullOrEmpty(productName)) + return; - return client; + UniqueUserAgents.Add(new ProductInfoHeaderValue(productName, productVersion ?? "")); } - public TClient CreateClient(IAzureContextContainer profile, string endpoint) where TClient : ServiceClient + public void RemoveUserAgent(string name) { - return CreateClient(profile, profile.DefaultContext.Subscription, endpoint); + UniqueUserAgents.RemoveWhere(p => string.Equals(p.Product.Name, name, StringComparison.OrdinalIgnoreCase)); } - public TClient CreateClient(IAzureContextContainer profile, IAzureSubscription subscription, string endpoint) where TClient : ServiceClient + public TClient CreateArmClient(IAzureContext context, string endpoint) where TClient : Microsoft.Rest.ServiceClient { -#if !NETSTANDARD - if (subscription == null) - { - throw new ArgumentException(Microsoft.Azure.Commands.ResourceManager.Common.Properties.Resources.InvalidDefaultSubscription); - } - - if (profile == null) - { - profile = new AzureSMProfile(Path.Combine(AzureSession.Instance.ProfileDirectory, AzureSession.Instance.ProfileFile)); - } + Debug.Assert(context != null); + var credentials = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context, endpoint); + return CreateCustomArmClient(context.Environment.GetEndpointAsUri(endpoint), credentials); + } - SubscriptionCloudCredentials creds = new TokenCloudCredentials(subscription.Id.ToString(), "fake_token"); - if (HttpMockServer.GetCurrentMode() != HttpRecorderMode.Playback) + public TClient CreateCustomArmClient(params object[] parameters) where TClient : Microsoft.Rest.ServiceClient + { + if (!(_serviceClients.FirstOrDefault(o => o is TClient) is TClient client)) { - ProfileClient profileClient = new ProfileClient(profile as AzureSMProfile); - AzureContext context = new AzureContext( - subscription, - profileClient.GetAccount(subscription.GetAccount()), - profileClient.GetEnvironmentOrDefault(subscription.GetEnvironment()) - ); - - creds = AzureSession.Instance.AuthenticationFactory.GetSubscriptionCloudCredentials(context); + client = _mockContext?.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); } - Uri endpointUri = profile.Environments.FirstOrDefault((e) => e.Name.Equals(subscription.GetEnvironment(), StringComparison.OrdinalIgnoreCase)).GetEndpointAsUri(endpoint); - return CreateCustomClient(creds, endpointUri); -#else - throw new NotSupportedException("AzureSMProfile is not supported in Azure PS on .Net Core."); -#endif - } - - public TClient CreateCustomClient(params object[] parameters) where TClient : ServiceClient - { - TClient client = ManagementClients.FirstOrDefault(o => o is TClient) as TClient; if (client == null) { - if (throwWhenNotAvailable) - { - throw new ArgumentException( - string.Format("TestManagementClientHelper class wasn't initialized with the {0} client.", - typeof(TClient).Name)); - } - else - { - var realClientFactory = new ClientFactory(); - var realClient = realClientFactory.CreateCustomClient(parameters); - var newRealClient = realClient.WithHandler(HttpMockServer.CreateInstance()); - - var initialTimeoutPropInfo = typeof(TClient).GetProperty("LongRunningOperationInitialTimeout", BindingFlags.Public | BindingFlags.Instance); - if (initialTimeoutPropInfo != null && initialTimeoutPropInfo.CanWrite) - { - initialTimeoutPropInfo.SetValue(newRealClient, 0, null); - } - - var retryTimeoutPropInfo = typeof(TClient).GetProperty("LongRunningOperationRetryTimeout", BindingFlags.Public | BindingFlags.Instance); - if (retryTimeoutPropInfo != null && retryTimeoutPropInfo.CanWrite) - { - retryTimeoutPropInfo.SetValue(newRealClient, 0, null); - } - - realClient.Dispose(); - return newRealClient; - } + var realClientFactory = new ClientFactory(); + var newParameters = new object[parameters.Length + 1]; + Array.Copy(parameters, 0, newParameters, 1, parameters.Length); + newParameters[0] = HttpMockServer.CreateInstance(); + client = realClientFactory.CreateCustomArmClient(newParameters); } - else + + if (TestMockSupport.RunningMocked && HttpMockServer.GetCurrentMode() != HttpRecorderMode.Record) { - if (!MoqClients && !client.GetType().Namespace.Contains("Castle.")) + if (client is IAzureClient azureClient) { - // Use the WithHandler method to create an extra reference to the http client - // this will prevent the httpClient from being disposed in a long-running test using - // the same client for multiple cmdlets - client = client.WithHandler(new PassThroughDelegatingHandler()); + azureClient.LongRunningOperationRetryTimeout = 0; } } @@ -154,146 +108,130 @@ public TClient CreateCustomClient(params object[] parameters) where TCl public HttpClient CreateHttpClient(string endpoint, ICredentials credentials) { - return CreateHttpClient(endpoint, ClientFactory.CreateHttpClientHandler(endpoint, credentials)); + throw new NotImplementedException(); } - public HttpClient CreateHttpClient(string serviceUrl, HttpMessageHandler effectiveHandler) + public HttpClient CreateHttpClient(string endpoint, HttpMessageHandler effectiveHandler) { - if (serviceUrl == null) - { - throw new ArgumentNullException("serviceUrl"); - } - if (effectiveHandler == null) - { - throw new ArgumentNullException("effectiveHandler"); - } - var mockHandler = HttpMockServer.CreateInstance(); - mockHandler.InnerHandler = effectiveHandler; - - HttpClient client = new HttpClient(mockHandler) - { - BaseAddress = new Uri(serviceUrl), - MaxResponseContentBufferSize = 30 * 1024 * 1024 - }; - - client.DefaultRequestHeaders.Accept.Clear(); - - return client; + throw new NotImplementedException(); } - public void AddAction(IClientAction action) + public DelegatingHandler[] GetCustomHandlers() { // Do nothing + return new DelegatingHandler[0]; } - public void RemoveAction(Type actionType) + public void AddHandler(T handler) where T : DelegatingHandler, ICloneable { // Do nothing } - public void AddHandler(T handler) where T : DelegatingHandler, ICloneable + public void RemoveHandler(Type handlerType) { // Do nothing } - public void RemoveHandler(Type handlerType) + public void AddAction(IClientAction action) { // Do nothing } - public DelegatingHandler[] GetCustomHandlers() + public void RemoveAction(Type actionType) { - // the equivalent of doing nothing - return new DelegatingHandler[0]; + // Do nothing } - public void AddUserAgent(string productName, string productVersion) + #region Hyak + + public TClient CreateClient(IAzureContext context, string endpoint) where TClient : Hyak.Common.ServiceClient { - if (string.IsNullOrEmpty(productName)) - { - return; - } - if (string.IsNullOrEmpty(productVersion)) - { - productVersion = ""; - } - this.UniqueUserAgents.Add(new ProductInfoHeaderValue(productName, productVersion)); + Debug.Assert(context != null); + + SubscriptionCloudCredentials creds = AzureSession.Instance.AuthenticationFactory.GetSubscriptionCloudCredentials(context, AzureEnvironment.Endpoint.ResourceManager); + TClient client = CreateCustomClient(creds, context.Environment.GetEndpointAsUri(endpoint)); + + return client; } - public void AddUserAgent(string productName) + public TClient CreateClient(IAzureContextContainer profile, string endpoint) where TClient : Hyak.Common.ServiceClient { - this.AddUserAgent(productName, ""); + return CreateClient(profile, profile.DefaultContext.Subscription, endpoint); } - public HashSet UniqueUserAgents { get; set; } - - public ProductInfoHeaderValue[] UserAgents + public TClient CreateClient(IAzureContextContainer profile, IAzureSubscription subscription, string endpoint) where TClient : Hyak.Common.ServiceClient { - get +#if !NETSTANDARD + if (subscription == null) { - return UniqueUserAgents?.ToArray(); + throw new ArgumentException(Microsoft.Azure.Commands.ResourceManager.Common.Properties.Resources.InvalidDefaultSubscription); } - } - /// - /// This class exists to allow adding an additional reference to the httpClient to prevent the client - /// from being disposed. Should not be used except in this mocked context. - /// - class PassThroughDelegatingHandler : DelegatingHandler - { - protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + if (profile == null) { - return base.SendAsync(request, cancellationToken); + profile = new AzureSMProfile(Path.Combine(AzureSession.Instance.ProfileDirectory, AzureSession.Instance.ProfileFile)); } - } - public TClient CreateArmClient(IAzureContext context, string endpoint) where TClient : Rest.ServiceClient - { - Debug.Assert(context != null); - var credentials = AzureSession.Instance.AuthenticationFactory.GetServiceClientCredentials(context); - var client = CreateCustomArmClient(credentials, context.Environment.GetEndpointAsUri(endpoint), - context.Subscription.Id); - return client; + SubscriptionCloudCredentials creds = new TokenCloudCredentials(subscription.Id.ToString(), "fake_token"); + if (HttpMockServer.GetCurrentMode() != HttpRecorderMode.Playback) + { + ProfileClient profileClient = new ProfileClient(profile as AzureSMProfile); + AzureContext context = new AzureContext(subscription, profileClient.GetAccount(subscription.GetAccount()), profileClient.GetEnvironmentOrDefault(subscription.GetEnvironment())); + creds = AzureSession.Instance.AuthenticationFactory.GetSubscriptionCloudCredentials(context); + } + Uri endpointUri = profile.Environments.FirstOrDefault((e) => e.Name.Equals(subscription.GetEnvironment(), StringComparison.OrdinalIgnoreCase)).GetEndpointAsUri(endpoint); + return CreateCustomClient(creds, endpointUri); +#else + throw new NotSupportedException("AzureSMProfile is not supported in Azure PS on .Net Core."); +#endif } - public TClient CreateCustomArmClient(params object[] parameters) where TClient : Rest.ServiceClient + public TClient CreateCustomClient(params object[] parameters) where TClient : Hyak.Common.ServiceClient { - TClient client = ManagementClients.FirstOrDefault(o => o is TClient) as TClient; - if (client == null) + if (!(_serviceClients.FirstOrDefault(o => o is TClient) is TClient client)) { - if (throwWhenNotAvailable) + var realClientFactory = new ClientFactory(); + var realClient = realClientFactory.CreateCustomClient(parameters); + var newRealClient = realClient.WithHandler(HttpMockServer.CreateInstance()); + + var initialTimeoutPropInfo = typeof(TClient).GetProperty("LongRunningOperationInitialTimeout", BindingFlags.Public | BindingFlags.Instance); + if (initialTimeoutPropInfo != null && initialTimeoutPropInfo.CanWrite) { - throw new ArgumentException( - string.Format("TestManagementClientHelper class wasn't initialized with the {0} client.", - typeof(TClient).Name)); + initialTimeoutPropInfo.SetValue(newRealClient, 0, null); } - else + + var retryTimeoutPropInfo = typeof(TClient).GetProperty("LongRunningOperationRetryTimeout", BindingFlags.Public | BindingFlags.Instance); + if (retryTimeoutPropInfo != null && retryTimeoutPropInfo.CanWrite) { - var realClientFactory = new ClientFactory(); - var newParameters = new object[parameters.Length + 1]; - Array.Copy(parameters, 0, newParameters, 1, parameters.Length); - newParameters[0] = HttpMockServer.CreateInstance(); - var realClient = realClientFactory.CreateCustomArmClient(newParameters); - return realClient; + retryTimeoutPropInfo.SetValue(newRealClient, 0, null); } - } - if (TestMockSupport.RunningMocked && HttpMockServer.GetCurrentMode() != HttpRecorderMode.Record) + realClient.Dispose(); + return newRealClient; + } + else { - IAzureClient azureClient = client as IAzureClient; - if (azureClient != null) + if (!MoqClients && !client.GetType().Namespace.Contains("Castle.")) { - azureClient.LongRunningOperationRetryTimeout = 0; + // Use the WithHandler method to create an extra reference to the http client + // this will prevent the httpClient from being disposed in a long-running test using + // the same client for multiple cmdlets + client = client.WithHandler(new PassThroughDelegatingHandler()); } } return client; } - public void RemoveUserAgent(string name) + class PassThroughDelegatingHandler : DelegatingHandler { - UniqueUserAgents.RemoveWhere((p) => string.Equals(p.Product.Name, name, StringComparison.OrdinalIgnoreCase)); + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + return base.SendAsync(request, cancellationToken); + } } + + #endregion } } diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockCommandRuntime.cs b/tools/TestFx/Mocks/MockCommandRuntime.cs similarity index 93% rename from tools/ScenarioTest.ResourceManager/Mocks/MockCommandRuntime.cs rename to tools/TestFx/Mocks/MockCommandRuntime.cs index fa1983f2c91b..20859febb3dd 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockCommandRuntime.cs +++ b/tools/TestFx/Mocks/MockCommandRuntime.cs @@ -15,7 +15,6 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Management.Automation; using System.Management.Automation.Host; @@ -44,16 +43,12 @@ public override string ToString() return "MockCommand"; } - [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations", - Justification = "Tests should not access this property")] public PSTransactionContext CurrentPSTransaction { get { throw new System.NotImplementedException(); } } - [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations", - Justification = "Tests should not access this property")] - public System.Management.Automation.Host.PSHost Host + public PSHost Host { get { @@ -94,17 +89,17 @@ public bool ShouldProcess(string target) public void ThrowTerminatingError(ErrorRecord errorRecord) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public bool TransactionAvailable() { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void WriteCommandDetail(string text) { - throw new System.NotImplementedException(); + throw new NotImplementedException(); } public void WriteDebug(string text) @@ -184,7 +179,6 @@ private void ThrowIfNotFromInvocationThread() class MockPSHost : PSHost { PSHostUserInterface _hostUI = new MockPSHostUI(); - Version _version = new Version(1, 0, 0); Guid _instanceId = Guid.NewGuid(); public override CultureInfo CurrentCulture { diff --git a/tools/TestFx/Mocks/MockContext.cs b/tools/TestFx/Mocks/MockContext.cs new file mode 100644 index 000000000000..a43abb87c1c3 --- /dev/null +++ b/tools/TestFx/Mocks/MockContext.cs @@ -0,0 +1,374 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using Microsoft.Azure.Commands.TestFx.DelegatingHandlers; +using Microsoft.Azure.Commands.TestFx.Recorder; +using Microsoft.Azure.Test.HttpRecorder; +using System; +using System.Collections.Generic; +using System.Net.Http; +using System.Reflection; + +namespace Microsoft.Rest.ClientRuntime.Azure.TestFramework +{ + public sealed class MockContext : IDisposable + { + //prevent multiple dispose events + private bool _disposed = false; + private readonly List _undoHandlers = new List(); + private TestEnvironment _testFxEnvironment; + + private MockContext() + { + } + + internal TestEnvironment TestFxEnvironment + { + get + { + if (_testFxEnvironment == null) + { + string envStr = Environment.GetEnvironmentVariable(ConnectionStringKeys.TestCSMOrgIdConnectionStringKey); + _testFxEnvironment = new TestEnvironment(envStr); + OptimizeTestRecordingFile = _testFxEnvironment.OptimizeRecordedFile; + } + + return _testFxEnvironment; + } + } + + internal bool OptimizeTestRecordingFile { get; set; } = false; + + /// + /// Return a new MockContext + /// + /// + public static MockContext Start( + string className, + [System.Runtime.CompilerServices.CallerMemberName] + string methodName = "testframework_failed") + { + var context = new MockContext(); + if (HttpMockServer.FileSystemUtilsObject == null) + { + HttpMockServer.FileSystemUtilsObject = new FileSystemUtils(); + } + HttpMockServer.Initialize(className, methodName); + + return context; + } + + /// + /// Return a new MockContext + /// + /// + public static MockContext Start( + Type type, + [System.Runtime.CompilerServices.CallerMemberName] + string methodName = "testframework_failed") + { + return Start(type.Name, methodName); + } + + /// + /// Get a test environment using default options + /// + /// The type of the service client to return + /// A Service client using credentials and base uri from the current environment + public T GetServiceClient(bool internalBaseUri = false, params DelegatingHandler[] handlers) where T : class + { + return GetServiceClient(TestFxEnvironment, internalBaseUri, handlers); + } + + /// + /// Get a test environment, allowing the test to customize the creation options + /// + /// + /// Delegating existingHandlers + /// + public T GetServiceClient(TestEnvironment currentEnvironment, bool internalBaseUri = false, params DelegatingHandler[] handlers) where T : class + { + return GetServiceClientWithCredentials(currentEnvironment, + currentEnvironment.TokenInfo[TokenAudience.Management], internalBaseUri, handlers); + } + + /// + /// Creates Graph client object + /// + /// + /// Delegating existingHandlers + /// + public T GetGraphServiceClient( + bool internalBaseUri = false, + params DelegatingHandler[] handlers) where T : class + { + //TestFxEnvironment = TestEnvironmentFactory.GetTestEnvironment(); + return GetGraphServiceClient(TestFxEnvironment, internalBaseUri, handlers); + } + + /// + /// Creates Graph client object + /// + /// + /// Delegating existingHandlers + /// + public T GetGraphServiceClient( + TestEnvironment currentEnvironment, + bool internalBaseUri = false, + params DelegatingHandler[] handlers) where T : class + { + if (!currentEnvironment.TokenInfo.ContainsKey(TokenAudience.Graph)) + { + throw new ArgumentNullException( + "currentEnvironment.TokenInfo[TokenAudience.Graph]", + "Unable to create Graph Management client because Graph authentication token was not acquired during Login."); + } + + return GetServiceClientWithCredentials( + currentEnvironment, + currentEnvironment.TokenInfo[TokenAudience.Graph], + currentEnvironment.Endpoints.GraphUri, + internalBaseUri, + handlers); + } + + /// + /// Get a test environment using default options + /// + /// The type of the service client to return + /// Credentials + /// Delegating existingHandlers + /// A Service client using credentials and base uri from the current environment + public T GetServiceClientWithCredentials(object credentials, params DelegatingHandler[] handlers) where T : class + { + return GetServiceClientWithCredentials(TestFxEnvironment, credentials, handlers: handlers); + } + + /// + /// Get a test environment, allowing the test to customize the creation options + /// + /// + /// Credentials + /// Delegating existingHandlers + /// + public T GetServiceClientWithCredentials( + TestEnvironment currentEnvironment, + object credentials, + bool internalBaseUri = false, + params DelegatingHandler[] handlers) where T : class + { + return GetServiceClientWithCredentials(currentEnvironment, credentials, currentEnvironment.BaseUri, internalBaseUri, handlers); + } + + /// + /// Get a test environment, allowing the test to customize the creation options + /// + /// + /// Credentials + /// Base Uri + /// Delegating existingHandlers + /// + public T GetServiceClientWithCredentials( + TestEnvironment currentEnvironment, + object credentials, + Uri baseUri, + bool internalBaseUri = false, + params DelegatingHandler[] handlers) where T : class + { + T client; + handlers = AddHandlers(currentEnvironment, handlers); + var constructors = typeof(T).GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic); + + ConstructorInfo constructor = null; + //We no longer use UseCustomUri function, rather check if BaseUri is notNull + //UseCustomeUri use to return true when BaseUri was set to some value + if ((currentEnvironment.BaseUri != null) && !internalBaseUri) + { + foreach (var c in constructors) + { + var parameters = c.GetParameters(); + if (parameters.Length == 3 && + parameters[0].ParameterType.Name == "Uri" && + parameters[1].ParameterType.Name == "ServiceClientCredentials" && + parameters[2].ParameterType.Name == "DelegatingHandler[]") + { + constructor = c; + break; + } + } + if (constructor == null) + { + throw new InvalidOperationException( + "can't find constructor (uri, ServiceClientCredentials, DelegatingHandler[]) to create client"); + } + client = constructor.Invoke(new object[] + { + baseUri, + credentials, + handlers + }) as T; + } + else + { + foreach (var c in constructors) + { + var parameters = c.GetParameters(); + if (parameters.Length == 2 && + parameters[0].ParameterType.Name == "ServiceClientCredentials" && + parameters[1].ParameterType.Name == "DelegatingHandler[]") + { + constructor = c; + break; + } + } + if (constructor == null) + { + throw new InvalidOperationException( + "can't find constructor (ServiceClientCredentials, DelegatingHandler[]) to create client"); + } + client = constructor.Invoke(new object[] + { + credentials, + handlers + }) as T; + } + + var subscriptionId = typeof(T).GetProperty("SubscriptionId"); + if (subscriptionId != null && currentEnvironment.SubscriptionId != null) + { + subscriptionId.SetValue(client, currentEnvironment.SubscriptionId); + } + + var tenantId = typeof(T).GetProperty("TenantId"); + if (tenantId != null && currentEnvironment.TenantId != null) + { + tenantId.SetValue(client, currentEnvironment.TenantId); + } + SetLongRunningOperationTimeouts(client); + return client; + } + + private void SetLongRunningOperationTimeouts(T client) where T : class + { + if (HttpMockServer.Mode == HttpRecorderMode.Playback) + { + PropertyInfo retryTimeout = typeof(T).GetProperty("LongRunningOperationRetryTimeout"); + if (retryTimeout != null) + { + retryTimeout.SetValue(client, 0); + } + } + } + + public DelegatingHandler[] AddHandlers(TestEnvironment currentEnvironment, + params DelegatingHandler[] existingHandlers) + { + HttpMockServer server; + + try + { + server = HttpMockServer.CreateInstance(); + } + catch (InvalidOperationException) + { + // mock server has never been initialized, we will need to initialize it. + HttpMockServer.Initialize("TestEnvironment", "InitialCreation"); + server = HttpMockServer.CreateInstance(); + } + + var handlers = new List(existingHandlers); + if (!MockServerInHandlers(handlers)) + { + handlers.Add(server); + } + + ResourceCleanerDelegatingHandler cleaner = new ResourceCleanerDelegatingHandler(currentEnvironment.TokenInfo[TokenAudience.Management]); + handlers.Add(cleaner); + _undoHandlers.Add(cleaner); + + return handlers.ToArray(); + } + + /// + /// Stop recording and Discard all undo information + /// + public void Stop() + { + if (HttpMockServer.Mode != HttpRecorderMode.Playback) + { + foreach (var undoHandler in _undoHandlers) + { + undoHandler.DeleteResourceGroups().ConfigureAwait(false).GetAwaiter().GetResult(); + } + } + + string recordedFilePath = HttpMockServer.Flush(); + + if (HttpMockServer.Mode == HttpRecorderMode.Record) + { + // this check should be removed once we make the optimizatoin default + if (OptimizeTestRecordingFile) + { + RecordedFiles procRecFile = new RecordedFiles(recordedFilePath); + procRecFile.CompactLroPolling(); + procRecFile.SerializeCompactData(); + } + } + } + + private static bool MockServerInHandlers(List handlers) + { + var result = false; + foreach (var handler in handlers) + { + if (HandlerContains(handler)) + { + result = true; + break; + } + } + + return result; + } + + private static bool HandlerContains(DelegatingHandler handler) + { + return (handler is T1 || (handler.InnerHandler != null + && handler.InnerHandler is DelegatingHandler + && HandlerContains(handler.InnerHandler as DelegatingHandler))); + } + + /// + /// Dispose only if we have not previously been disposed + /// + /// true if we should dispose, otherwise false + private void Dispose(bool disposing) + { + if (disposing && !_disposed) + { + Stop(); + _disposed = true; + } + } + + /// + /// Dispose the object + /// + public void Dispose() + { + Dispose(true); + } + } +} diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockPowerShellTokenCacheProvider.cs b/tools/TestFx/Mocks/MockPowerShellTokenCacheProvider.cs similarity index 90% rename from tools/ScenarioTest.ResourceManager/Mocks/MockPowerShellTokenCacheProvider.cs rename to tools/TestFx/Mocks/MockPowerShellTokenCacheProvider.cs index e61100805b75..692966ee6fa3 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockPowerShellTokenCacheProvider.cs +++ b/tools/TestFx/Mocks/MockPowerShellTokenCacheProvider.cs @@ -1,4 +1,4 @@ -// ---------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------- // // Copyright Microsoft Corporation // Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,12 +13,9 @@ // ---------------------------------------------------------------------------------- using Azure.Identity; - using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Identity.Client; using System; -using System.Collections.Generic; -using System.Text; namespace Microsoft.Azure.Commands.ScenarioTest.Mocks { diff --git a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs b/tools/TestFx/Mocks/MockTokenAuthenticationFactory.cs similarity index 69% rename from tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs rename to tools/TestFx/Mocks/MockTokenAuthenticationFactory.cs index 2667c198c951..406834ede460 100644 --- a/tools/ScenarioTest.ResourceManager/Mocks/MockTokenAuthenticationFactory.cs +++ b/tools/TestFx/Mocks/MockTokenAuthenticationFactory.cs @@ -12,16 +12,13 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.Authentication.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Rest; using System; using System.Security; -namespace Microsoft.WindowsAzure.Commands.Common.Test.Mocks +namespace Microsoft.Azure.Commands.TestFx.Mocks { public class MockTokenAuthenticationFactory : IAuthenticationFactory, IHyakAuthenticationFactory { @@ -33,9 +30,9 @@ public MockTokenAuthenticationFactory() { Token = new MockAccessToken { - UserId = "Test", + UserId = "MockUser", LoginType = LoginType.OrgId, - AccessToken = "abc" + AccessToken = "MockAccessToken" }; TokenProvider = (account, environment, tenant) => Token = new MockAccessToken @@ -56,7 +53,7 @@ public MockTokenAuthenticationFactory(string userId, string accessToken) AccessToken = accessToken, }; - TokenProvider = ((account, environment, tenant) => Token); + TokenProvider = (account, environment, tenant) => Token; } public MockTokenAuthenticationFactory(string userId, string accessToken, string tenantId) @@ -69,23 +66,14 @@ public MockTokenAuthenticationFactory(string userId, string accessToken, string TenantId = tenantId }; - TokenProvider = ((account, environment, tenant) => Token); + TokenProvider = (account, environment, tenant) => Token; } - - public IAccessToken Authenticate( - IAzureAccount account, - IAzureEnvironment environment, - string tenant, - SecureString password, - string promptBehavior, - Action promptActionr, - IAzureTokenCache tokenCache, - string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId) + public IAccessToken Authenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Action promptAction, IAzureTokenCache tokenCache, string resourceId = "ActiveDirectoryServiceEndpointResourceId") { if (account.Id == null) { - account.Id = "test"; + account.Id = "MockAccount"; } if (TokenProvider == null) @@ -103,43 +91,34 @@ public IAccessToken Authenticate( } } - public IAccessToken Authenticate( - IAzureAccount account, - IAzureEnvironment environment, - string tenant, - SecureString password, - string promptBehavior, - Action promptAction, - string resourceId = AzureEnvironment.Endpoint.ActiveDirectoryServiceEndpointResourceId) + public IAccessToken Authenticate(IAzureAccount account, IAzureEnvironment environment, string tenant, SecureString password, string promptBehavior, Action promptAction, string resourceId = "ActiveDirectoryServiceEndpointResourceId") { return Authenticate(account, environment, tenant, password, promptBehavior, promptAction, AzureSession.Instance.TokenCache, resourceId); } - public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context) + public ServiceClientCredentials GetServiceClientCredentials(IAzureContext context) { - return new AccessTokenCredential(context.Subscription.GetId(), Token); + return new TokenCredentials(Token.AccessToken); } - public Microsoft.Rest.ServiceClientCredentials GetServiceClientCredentials(IAzureContext context) + public ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint) { - return new RenewingTokenCredential(Token); + return new TokenCredentials(Token.AccessToken); } - - public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context, string targetEndpoint) + public ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) { - return new AccessTokenCredential(context.Subscription.GetId(), Token); + throw new NotImplementedException(); } - - public ServiceClientCredentials GetServiceClientCredentials(IAzureContext context, string targetEndpoint) + public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context) { - return new RenewingTokenCredential(Token); + return new AccessTokenCredential(context.Subscription.GetId(), Token); } - public Rest.ServiceClientCredentials GetServiceClientCredentials(string accessToken, Func renew = null) + public SubscriptionCloudCredentials GetSubscriptionCloudCredentials(IAzureContext context, string targetEndpoint) { - throw new System.NotImplementedException(); + return new AccessTokenCredential(context.Subscription.GetId(), Token); } public void RemoveUser(IAzureAccount account, IAzureTokenCache tokenCache) diff --git a/tools/ScenarioTest.ResourceManager/PSCmdletExtensions.cs b/tools/TestFx/PSCmdletExtensions.cs similarity index 96% rename from tools/ScenarioTest.ResourceManager/PSCmdletExtensions.cs rename to tools/TestFx/PSCmdletExtensions.cs index dc4c8dfd8437..d3e487f7d8dc 100644 --- a/tools/ScenarioTest.ResourceManager/PSCmdletExtensions.cs +++ b/tools/TestFx/PSCmdletExtensions.cs @@ -15,9 +15,8 @@ using System; using System.Management.Automation; using System.Reflection; -using System.Threading; -namespace Microsoft.WindowsAzure.Commands.ScenarioTest +namespace Microsoft.Azure.Commands.TestFx { public static class PSCmdletExtensions { diff --git a/tools/ScenarioTest.ResourceManager/PageExtensions.cs b/tools/TestFx/PageExtensions.cs similarity index 95% rename from tools/ScenarioTest.ResourceManager/PageExtensions.cs rename to tools/TestFx/PageExtensions.cs index 3168f0b843ef..6c9884dcd9fd 100644 --- a/tools/ScenarioTest.ResourceManager/PageExtensions.cs +++ b/tools/TestFx/PageExtensions.cs @@ -16,7 +16,7 @@ using System.Collections.Generic; using System.Reflection; -namespace Microsoft.WindowsAzure.Commands.ScenarioTest +namespace Microsoft.Azure.Commands.TestFx { public static class PageExtensions { diff --git a/tools/TestFx/PowerShellExtensions.cs b/tools/TestFx/PowerShellExtensions.cs new file mode 100644 index 000000000000..085e1c7f7421 --- /dev/null +++ b/tools/TestFx/PowerShellExtensions.cs @@ -0,0 +1,109 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.ServiceManagement.Common.Models; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Management.Automation; +using System.Management.Automation.Runspaces; + +namespace Microsoft.Azure.Commands.TestFx +{ + public static class PowerShellExtensions + { + public static void LogPowerShellException( + this System.Management.Automation.PowerShell powershell, + Exception runtimeException, + XunitTracingInterceptor xunitLogger) + { + if (xunitLogger != null) + { + xunitLogger.Information($"Caught Exception: {runtimeException}"); + xunitLogger.Information($"Message: {runtimeException.Message}"); + } + + if (runtimeException is IContainsErrorRecord recordContainer) + { + ErrorRecord record = recordContainer.ErrorRecord; + xunitLogger?.Information(FormatErrorRecord(record)); + } + + if (runtimeException.InnerException != null) + { + powershell.LogPowerShellException(runtimeException.InnerException, xunitLogger); + } + } + + internal static string FormatErrorRecord(ErrorRecord record) + { + return $"PowerShell Error Record: {record}\nException:{record.Exception}\nDetails:{record.ErrorDetails}\nScript Stack Trace: {record.ScriptStackTrace}\n: Target: {record.TargetObject}\n"; + } + + public static void LogPowerShellResults( + this System.Management.Automation.PowerShell powershell, + Collection output, + XunitTracingInterceptor xunitLogger) + { + if (output != null) + { + LogPowerShellStream(xunitLogger, output, "OUTPUT"); + } + + if (xunitLogger != null && + powershell.Commands != null && + powershell.Commands.Commands != null && + powershell.Commands.Commands.Count > 0) + { + xunitLogger.Information("================== COMMANDS =======================\n"); + + foreach (Command command in powershell.Commands.Commands) + { + xunitLogger.Information($"{command.CommandText}\n"); + } + + xunitLogger.Information("===================================================\n"); + } + + LogPowerShellStream(xunitLogger, powershell.Streams.Debug, "DEBUG"); + LogPowerShellStream(xunitLogger, powershell.Streams.Error.Select(FormatErrorRecord).ToList(), "ERROR"); + LogPowerShellStream(xunitLogger, powershell.Streams.Progress, "PROGRESS"); + LogPowerShellStream(xunitLogger, powershell.Streams.Verbose, "VERBOSE"); + LogPowerShellStream(xunitLogger, powershell.Streams.Warning, "WARNING"); + } + + private static void LogPowerShellStream( + XunitTracingInterceptor xunitLogger, + ICollection stream, + string name) + { + if (xunitLogger != null && stream != null && stream.Count > 0) + { + xunitLogger.Information("---------------------------------------------------------------\n"); + xunitLogger.Information($"{name} STREAM\n"); + xunitLogger.Information("---------------------------------------------------------------\n"); + foreach (T item in stream) + { + if (item != null) + { + xunitLogger.Information($"{item}\n"); + } + } + xunitLogger.Information("---------------------------------------------------------------\n"); + xunitLogger.Information(""); + } + } + } +} diff --git a/tools/ScenarioTest.ResourceManager/RMTestBase.cs b/tools/TestFx/RMTestBase.cs similarity index 97% rename from tools/ScenarioTest.ResourceManager/RMTestBase.cs rename to tools/TestFx/RMTestBase.cs index 0d48246e393f..2f9d4b154fd5 100644 --- a/tools/ScenarioTest.ResourceManager/RMTestBase.cs +++ b/tools/TestFx/RMTestBase.cs @@ -16,7 +16,7 @@ using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.ScenarioTest; -using Microsoft.WindowsAzure.Commands.Common.Test.Mocks; +using Microsoft.Azure.Commands.TestFx.Mocks; using Microsoft.WindowsAzure.Commands.Utilities.Common; using Moq; using System; @@ -52,7 +52,7 @@ public void BaseSetup() Type = AzureAccount.AccountType.User, }; account.SetSubscriptions(newGuid.ToString()); - var subscription = new AzureSubscription { Id = newGuid.ToString(), Name = "test"}; + var subscription = new AzureSubscription { Id = newGuid.ToString(), Name = "test" }; subscription.SetAccount("test"); subscription.SetEnvironment(EnvironmentName.AzureCloud); currentProfile.DefaultContext = new AzureContext( diff --git a/tools/TestFx/Recorder/AssetNames.cs b/tools/TestFx/Recorder/AssetNames.cs new file mode 100644 index 000000000000..27cd40a5a76c --- /dev/null +++ b/tools/TestFx/Recorder/AssetNames.cs @@ -0,0 +1,86 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class AssetNames : IEnumerable>> + { + public Dictionary> Names { get; private set; } + + public AssetNames() + { + Names = new Dictionary>(); + } + + public AssetNames(Dictionary> assetNames) + { + Names = new Dictionary>(assetNames); + } + + public void Enqueue(string testName, string assetName) + { + if (!Names.ContainsKey(testName)) + { + Names[testName] = new Queue(); + } + Names[testName].Enqueue(assetName); + } + + public void Enqueue(string testName, string[] names) + { + if (!Names.ContainsKey(testName)) + { + Names[testName] = new Queue(); + } + + Array.ForEach(names, a => Names[testName].Enqueue(a)); + } + + public void EnqueueRange(Dictionary names) + { + if (names != null) + { + foreach (KeyValuePair item in names) + { + Enqueue(item.Key, item.Value); + } + } + } + + public Queue this[string testName] + { + get { return Names[testName]; } + set { Names[testName] = value; } + } + + public bool ContainsKey(string testName) + { + return Names.ContainsKey(testName); + } + + public IEnumerator>> GetEnumerator() + { + return Names.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return Names.GetEnumerator(); + } + } +} diff --git a/tools/TestFx/Recorder/CompactLroEntries.cs b/tools/TestFx/Recorder/CompactLroEntries.cs new file mode 100644 index 000000000000..8d4b89641b1f --- /dev/null +++ b/tools/TestFx/Recorder/CompactLroEntries.cs @@ -0,0 +1,121 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class CompactLroEntries + { + private readonly Queue _entryPackCloneQueue; + private readonly Stack _lroStack; + + RecordEntryPack _processedEntryPack; + + public CompactLroEntries() + { + _entryPackCloneQueue = new Queue(); + _lroStack = new Stack(); + } + + public string ProcessorName { get => "CompactLroEntries"; protected set => ProcessorName = value; } + + public RecordEntryPack ProcessedEntryPack + { + get + { + if (_processedEntryPack == null) + { + _processedEntryPack = new RecordEntryPack(); + } + + return _processedEntryPack; + } + } + + public void Process(RecordEntryPack recordEntryPack) + { + foreach (RecordEntry rec in recordEntryPack.Entries) + { + if (IsLroEntry(rec)) + { + _lroStack.Push(rec); + } + else + { + if (_lroStack.Any()) + { + UpdateCloneQueueFromStack(); + } + + _entryPackCloneQueue.Enqueue(rec); + } + } + + if (_lroStack.Any()) + { + UpdateCloneQueueFromStack(); + } + + if (_entryPackCloneQueue.Any()) + { + ProcessedEntryPack.Entries = _entryPackCloneQueue.ToList(); + } + } + + private void UpdateCloneQueueFromStack() + { + int takeLastCount = 2; + if (_lroStack.Any()) + { + Stack tempStack = new Stack(); + int popCount = 1; + + while (_lroStack.Count > 0) + { + if (popCount <= takeLastCount) + { + tempStack.Push(_lroStack.Pop()); + popCount++; + } + else + { + _lroStack.Clear(); + break; + } + } + + while (tempStack.Count > 0) + { + _entryPackCloneQueue.Enqueue(tempStack.Pop()); + } + } + } + + internal bool IsLroEntry(RecordEntry re) + { + return re.RequestHeaders.ContainsKey("RecordPlaybackPerfImpact"); + } + } + + public interface IRecordingProcessor + { + string ProcessorName { get; } + + void Process(RecordEntryPack recordEntryPack); + + RecordEntryPack ProcessedEntryPack { get; } + } +} diff --git a/tools/TestFx/Recorder/FileSystemUtils.cs b/tools/TestFx/Recorder/FileSystemUtils.cs new file mode 100644 index 000000000000..e31008f703e0 --- /dev/null +++ b/tools/TestFx/Recorder/FileSystemUtils.cs @@ -0,0 +1,72 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.IO; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class FileSystemUtils + { + public void CreateDirectory(string path) + { + Directory.CreateDirectory(path); + } + + public void DeleteDirectory(string dir) + { + Directory.Delete(dir); + } + + public void DeleteFile(string path) + { + File.Delete(path); + } + + public bool DirectoryExists(string path) + { + return Directory.Exists(path); + } + + public bool FileExists(string path) + { + return File.Exists(path); + } + + public string[] GetDirectories(string sourceDirName, string pattern, bool recursive) + { + return Directory.GetDirectories(sourceDirName, pattern, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); + } + + public string GetEnvironmentVariable(string variable) + { + return Environment.GetEnvironmentVariable(variable); + } + + public string[] GetFiles(string sourceDirName, string pattern, bool recursive) + { + return Directory.GetFiles(sourceDirName, pattern, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); + } + + public string ReadFileAsText(string path) + { + return File.ReadAllText(path); + } + + public void WriteFile(string path, string contents) + { + File.WriteAllText(path, contents); + } + } +} diff --git a/tools/TestFx/Recorder/IRecordMatcher.cs b/tools/TestFx/Recorder/IRecordMatcher.cs new file mode 100644 index 000000000000..f78c0f8ffe76 --- /dev/null +++ b/tools/TestFx/Recorder/IRecordMatcher.cs @@ -0,0 +1,25 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Net.Http; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public interface IRecordMatcher + { + string GetMatchingKey(RecordEntry recordEntry); + + string GetMatchingKey(HttpRequestMessage request); + } +} diff --git a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithApiExclusion.cs b/tools/TestFx/Recorder/PermissiveRecordMatcherWithApiExclusion.cs similarity index 98% rename from tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithApiExclusion.cs rename to tools/TestFx/Recorder/PermissiveRecordMatcherWithApiExclusion.cs index 6915fc186173..ea13d805520e 100644 --- a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithApiExclusion.cs +++ b/tools/TestFx/Recorder/PermissiveRecordMatcherWithApiExclusion.cs @@ -12,14 +12,13 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Azure.Test.HttpRecorder; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace Microsoft.WindowsAzure.Commands.ScenarioTest +namespace Microsoft.Azure.Commands.TestFx.Recorder { // Excludes api version when matching mocked records. // If alternate api version is provided, uses that to match records else removes the api-version matching. diff --git a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithResourceApiExlcusion.cs b/tools/TestFx/Recorder/PermissiveRecordMatcherWithResourceApiExclusion.cs similarity index 98% rename from tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithResourceApiExlcusion.cs rename to tools/TestFx/Recorder/PermissiveRecordMatcherWithResourceApiExclusion.cs index daa60ccfefb0..26b0c6e5b022 100644 --- a/tools/ScenarioTest.ResourceManager/PermissiveRecordMatcherWithResourceApiExlcusion.cs +++ b/tools/TestFx/Recorder/PermissiveRecordMatcherWithResourceApiExclusion.cs @@ -13,15 +13,13 @@ // ---------------------------------------------------------------------------------- using Microsoft.Azure.Management.Internal.Resources.Utilities.Models; -using Microsoft.Azure.Test.HttpRecorder; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Text; using System.Text.RegularExpressions; -namespace Microsoft.WindowsAzure.Commands.ScenarioTest +namespace Microsoft.Azure.Commands.TestFx.Recorder { // Excludes api version when matching mocked records. // If alternate api version is provided, uses that to match records else removes the api-version matching. diff --git a/tools/TestFx/Recorder/RecordEntry.cs b/tools/TestFx/Recorder/RecordEntry.cs new file mode 100644 index 000000000000..6f172f833ecd --- /dev/null +++ b/tools/TestFx/Recorder/RecordEntry.cs @@ -0,0 +1,131 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class RecordEntry + { + public string RequestUri { get; set; } + + public string EncodedRequestUri { get; set; } + + public string RequestMethod { get; set; } + + [JsonIgnore] + public RecordEntryContentType RequestContentType { get; set; } + + public Dictionary> RequestHeaders { get; set; } + + public string RequestBody { get; set; } + + [JsonIgnore] + public RecordEntryContentType ResponseContentType { get; set; } + + public Dictionary> ResponseHeaders { get; set; } + + public string ResponseBody { get; set; } + + public HttpStatusCode StatusCode { get; set; } + + public RecordEntry() + { + + } + + public RecordEntry(RecordEntry record) : this(record.GetResponse()) + { + + } + + public RecordEntry(HttpResponseMessage response) + { + HttpRequestMessage request = response.RequestMessage; + RequestUri = request.RequestUri.ToString(); + EncodedRequestUri = RecorderUtilities.EncodeUriAsBase64(request.RequestUri); + RequestMethod = request.Method.Method; + + RequestHeaders = new Dictionary>(); + ResponseHeaders = new Dictionary>(); + + RequestBody = string.Empty; + ResponseBody = string.Empty; + + RequestContentType = DetectContentType(request.Content); + ResponseContentType = DetectContentType(response.Content); + + request.Headers.ForEach(h => RequestHeaders.Add(h.Key, h.Value.ToList())); + response.Headers.ForEach(h => ResponseHeaders.Add(h.Key, h.Value.ToList())); + + StatusCode = response.StatusCode; + + if (RequestContentType != RecordEntryContentType.Null) + { + RequestBody = RecorderUtilities.FormatHttpContent(request.Content); + request.Content.Headers.ForEach(h => RequestHeaders.Add(h.Key, h.Value.ToList())); + } + + if (ResponseContentType != RecordEntryContentType.Null) + { + ResponseBody = RecorderUtilities.FormatHttpContent(response.Content); + response.Content.Headers.ForEach(h => ResponseHeaders.Add(h.Key, h.Value.ToList())); + } + } + + public HttpResponseMessage GetResponse() + { + HttpResponseMessage response = new HttpResponseMessage(); + response.StatusCode = StatusCode; + ResponseHeaders.ForEach(h => response.Headers.TryAddWithoutValidation(h.Key, h.Value)); + ResponseContentType = RecorderUtilities.GetContetTypeFromHeaders(ResponseHeaders); + response.Content = RecorderUtilities.CreateHttpContent(ResponseBody, ResponseContentType); + ResponseHeaders.ForEach(h => response.Content.Headers.TryAddWithoutValidation(h.Key, h.Value)); + return response; + } + + private RecordEntryContentType DetectContentType(HttpContent content) + { + RecordEntryContentType contentType = RecordEntryContentType.Null; + + if (content != null) + { + if (RecorderUtilities.IsHttpContentBinary(content)) + { + contentType = RecordEntryContentType.Binary; + } + else + { + contentType = RecordEntryContentType.Ascii; + } + } + + return contentType; + } + } + + /// + /// Request/Response content type enum + /// + public enum RecordEntryContentType + { + Binary, + Ascii, + Null + } +} diff --git a/tools/TestFx/Recorder/RecordEntryPack.cs b/tools/TestFx/Recorder/RecordEntryPack.cs new file mode 100644 index 000000000000..c1bd012bbff2 --- /dev/null +++ b/tools/TestFx/Recorder/RecordEntryPack.cs @@ -0,0 +1,60 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Newtonsoft.Json; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class RecordEntryPack + { + [JsonIgnore] + public List RRInfoRecordEntry { get; set; } + + public List Entries { get; set; } + + public Dictionary> Names { get; set; } + + public Dictionary Variables { get; set; } + + public RecordEntryPack() + { + Entries = new List(); + RRInfoRecordEntry = new List(); + } + + public void Serialize(string path) + { + RecorderUtilities.SerializeJson(this, path); + } + + public static RecordEntryPack Deserialize(string path) + { + return RecorderUtilities.DeserializeJson(path); + } + + public RecordEntryPack Deserialize(string path, bool extractMetaData) + { + RecordEntryPack recordPack = Deserialize(path); + + if (recordPack != null && extractMetaData) + { + RRInfoRecordEntry.AddRange(recordPack.Entries.Select(re => new RequestResponseInfo(re))); + } + + return recordPack; + } + } +} diff --git a/tools/TestFx/Recorder/RecordedFiles.cs b/tools/TestFx/Recorder/RecordedFiles.cs new file mode 100644 index 000000000000..6c304ce37bcf --- /dev/null +++ b/tools/TestFx/Recorder/RecordedFiles.cs @@ -0,0 +1,68 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class RecordedFiles + { + public string OriginalFilePath { get; private set; } + + public string BackupFilePath { get; set; } + + public RecordEntryPack OriginalPack { get; } + + public RecordEntryPack ProcessedPack { get; internal set; } + + public RecordedFiles() + { + + } + + public RecordedFiles(string recordedFilePath) : this() + { + if (File.Exists(recordedFilePath)) + { + OriginalPack = RecordEntryPack.Deserialize(recordedFilePath); + OriginalFilePath = recordedFilePath; + BackupFilePath = string.Concat(Path.Combine(Path.GetDirectoryName(recordedFilePath), Path.GetFileNameWithoutExtension(recordedFilePath)), ".pijson"); + } + } + + public void CompactLroPolling() + { + CompactLroEntries compactLro = new CompactLroEntries(); + compactLro.Process(OriginalPack); + ProcessedPack = compactLro.ProcessedEntryPack; + ProcessedPack.Variables = OriginalPack.Variables; + ProcessedPack.Names = OriginalPack.Names; + } + + public void SerializeCompactData(string filePath = "") + { + if (string.IsNullOrEmpty(filePath)) + { + ProcessedPack.Serialize(OriginalFilePath); + } + else + { + ProcessedPack.Serialize(filePath); + } + + OriginalPack.Serialize(BackupFilePath); + } + } +} diff --git a/tools/TestFx/Recorder/RecorderUtilities.cs b/tools/TestFx/Recorder/RecorderUtilities.cs new file mode 100644 index 000000000000..9a0b293bd529 --- /dev/null +++ b/tools/TestFx/Recorder/RecorderUtilities.cs @@ -0,0 +1,329 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Test.HttpRecorder; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Text.RegularExpressions; +using System.Xml.Linq; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public static class RecorderUtilities + { + private const string SanitizeValue = "Sanitized"; + + private static Regex _binaryMimeRegex = new Regex("(image/*|audio/*|video/*|application/octet-stream|multipart/form-data)"); + + public static List JsonPathSanitizers { get; } = new List(); + + static RecorderUtilities() + { + JsonPathSanitizers.Add("$..primaryKey"); + JsonPathSanitizers.Add("$..secondaryKey"); + JsonPathSanitizers.Add("$..primaryConnectionString"); + JsonPathSanitizers.Add("$..secondaryConnectionString"); + JsonPathSanitizers.Add("$..connectionString"); + } + + public static bool IsHttpContentBinary(HttpContent content) + { + var contentType = content?.Headers?.ContentType?.MediaType; + return IsHttpContentBinary(contentType); + } + + public static bool IsHttpContentBinary(string contentType) + { + if (contentType == null) + return false; + + return _binaryMimeRegex.IsMatch(contentType); + } + + public static string SerializeBinary(byte[] content) + { + return Convert.ToBase64String(content); + } + + public static byte[] DeserializeBinary(string content) + { + return Convert.FromBase64String(content); + } + + public static string FormatString(string content) + { + if (IsXml(content)) + return TryFormatXml(content); + + if (IsJson(content)) + return TryFormatJson(content); + + return content; + } + + public static RecordEntryContentType GetContetTypeFromHeaders(Dictionary> responseHeaders) + { + string mimeType = string.Empty; + RecordEntryContentType contentType = RecordEntryContentType.Null; + var header = responseHeaders.Where(hkv => hkv.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)); + + if (header.Any()) + { + mimeType = header.First().Value?.First(); + } + + if (!string.IsNullOrWhiteSpace(mimeType)) + { + if (IsHttpContentBinary(mimeType)) + { + contentType = RecordEntryContentType.Binary; + } + else + { + contentType = RecordEntryContentType.Ascii; + } + } + + return contentType; + } + + public static string FormatHttpContent(HttpContent httpContent) + { + string formattedContent; + if (IsHttpContentBinary(httpContent)) + { + formattedContent = Convert.ToBase64String(httpContent.ReadAsByteArrayAsync().Result); + } + else + { + formattedContent = FormatString(httpContent.ReadAsStringAsync().Result); + } + + return formattedContent; + } + + public static HttpContent CreateHttpContent(string contentData, RecordEntryContentType recordContentType) + { + HttpContent createdContent = null; + + switch (recordContentType) + { + case RecordEntryContentType.Binary: + { + try + { + byte[] hashBytes = Convert.FromBase64String(contentData); + if (hashBytes != null) + { + createdContent = new ByteArrayContent(hashBytes); + } + } + catch + { + if (contentData != null) + createdContent = new StringContent(contentData); + else + createdContent = new StringContent(string.Empty); + } + break; + } + case RecordEntryContentType.Ascii: + { + createdContent = new StringContent(contentData); + break; + } + case RecordEntryContentType.Null: + default: + { + createdContent = new StringContent(string.Empty); + break; + } + } + + return createdContent; + } + + /// + /// Formats the given XML into indented way. + /// + /// The input xml string + /// The formatted xml string + public static string TryFormatXml(string content) + { + try + { + XDocument doc = XDocument.Parse(content); + return doc.ToString(); + } + catch + { + return content; + } + } + + /// + /// Checks if the content is valid XML or not. + /// + /// The text to check + /// True if XML, false otherwise + public static bool IsXml(string content) + { + try + { + XDocument doc = XDocument.Parse(content); + return true; + } + catch + { + return false; + } + } + + public static string TryFormatJson(string content) + { + try + { + JToken parsedJson = JsonConvert.DeserializeObject(content); + foreach (var jsonPath in JsonPathSanitizers) + { + foreach (JToken token in parsedJson.SelectTokens(jsonPath)) + { + token.Replace(SanitizeValue); + } + } + return JsonConvert.SerializeObject(parsedJson, Formatting.Indented); + } + catch + { + return content; + } + } + + public static bool IsJson(string content) + { + content = content.Trim(); + return content.StartsWith("{") && content.EndsWith("}") + || content.StartsWith("[") && content.EndsWith("]"); + } + + /// + /// Perform an action on each element of a sequence. + /// + /// Type of elements in the sequence. + /// The sequence. + /// The action to perform. + internal static void ForEach(this IEnumerable sequence, Action action) + { + Debug.Assert(sequence != null, "sequence cannot be null!"); + Debug.Assert(action != null, "action cannot be null!"); + + foreach (T element in sequence) + { + action(element); + } + } + + public static void SerializeJson(T data, string path) + { + // TypeNameAssemblyFormat == Simple = 0, Full = 1 + // (we have an issue with duplicate namespace between newtonsoft and System.Runtime.Serialization. + // Once we upgrade to newtonsoft 11.x, we can start using TypeNameAssemblyFormatHandling instead) + HttpMockServer.FileSystemUtilsObject.WriteFile( + path, JsonConvert.SerializeObject(data, Formatting.Indented, new JsonSerializerSettings + { +#if net452 + TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, +#elif !net452 + TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple, +#endif + TypeNameHandling = TypeNameHandling.None + })); + } + + public static T DeserializeJson(string path) + { + // TypeNameAssemblyFormat == Simple = 0, Full = 1 + // (we have an issue with duplicate namespace between newtonsoft and System.Runtime.Serialization. + // Once we upgrade to newtonsoft 11.x, we can start using TypeNameAssemblyFormatHandling instead) + string json = HttpMockServer.FileSystemUtilsObject.ReadFileAsText(path); + return JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { +#if net452 + TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, +#elif !net452 + TypeNameAssemblyFormatHandling = TypeNameAssemblyFormatHandling.Simple, +#endif + TypeNameHandling = TypeNameHandling.None + }); + } + + public static void EnsureDirectoryExists(string dir) + { + if (!HttpMockServer.FileSystemUtilsObject.DirectoryExists(dir)) + { + HttpMockServer.FileSystemUtilsObject.CreateDirectory(dir); + } + } + + public static void CleanDirectory(string dir) + { + if (HttpMockServer.FileSystemUtilsObject.DirectoryExists(dir)) + { + foreach (string file in HttpMockServer.FileSystemUtilsObject.GetFiles(dir, "*.*", true)) + { + HttpMockServer.FileSystemUtilsObject.DeleteFile(file); + } + foreach (string subDirectory in HttpMockServer.FileSystemUtilsObject.GetDirectories(dir, "*", true)) + { + HttpMockServer.FileSystemUtilsObject.DeleteDirectory(subDirectory); + } + } + } + + public static string EncodeUriAsBase64(Uri requestUri) + { + return EncodeUriAsBase64(requestUri.PathAndQuery); + } + + public static string EncodeUriAsBase64(string uriToEncode) + { + byte[] encodedUri = Encoding.UTF8.GetBytes(uriToEncode); + return Convert.ToBase64String(encodedUri); + } + + public static string DecodeBase64AsUri(string uriToDecode) + { + if (string.IsNullOrEmpty(uriToDecode)) + return uriToDecode; + + string[] uriSplit = uriToDecode.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); + if (uriSplit.Length < 2) + return uriToDecode; + + string headers = string.Empty; + if (uriSplit.Length > 2) + { + headers = " " + string.Join(" ", uriSplit.Skip(2)); + } + byte[] encodedUri = Convert.FromBase64String(uriSplit[1]); + return string.Format("{0} {1}{2}", uriSplit[0], Encoding.UTF8.GetString(encodedUri, 0, encodedUri.Length), headers); + } + } +} diff --git a/tools/TestFx/Recorder/Records.cs b/tools/TestFx/Recorder/Records.cs new file mode 100644 index 000000000000..4dea79dc8bc5 --- /dev/null +++ b/tools/TestFx/Recorder/Records.cs @@ -0,0 +1,89 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class Records + { + private readonly Dictionary> _sessionRecords; + + private readonly IRecordMatcher _matcher; + + public Records(IRecordMatcher matcher) : this(new Dictionary>(), matcher) + { + + } + + public Records(Dictionary> records, IRecordMatcher matcher) + { + _sessionRecords = new Dictionary>(records); + _matcher = matcher; + } + + public void Enqueue(RecordEntry record) + { + string recordKey = _matcher.GetMatchingKey(record); + if (!_sessionRecords.ContainsKey(recordKey)) + { + _sessionRecords[recordKey] = new Queue(); + } + _sessionRecords[recordKey].Enqueue(record); + } + + public Queue this[string key] + { + get + { + if (!_sessionRecords.ContainsKey(key)) + throw new KeyNotFoundException($"Unable to find a matching HTTP request for URL '{RecorderUtilities.DecodeBase64AsUri(key)}'. Calling method {GetCallingMethodName()}()."); + + return _sessionRecords[key]; + } + set { _sessionRecords[key] = value; } + } + + private string GetCallingMethodName([CallerMemberName]string methodName="Getting_CallingMethodName_Failed_Your_Test_Will_Fail") + { + return methodName; + } + + public IEnumerable GetAllEntities() + { + foreach (var queues in _sessionRecords.Values) + { + while (queues.Count > 0) + { + yield return queues.Dequeue(); + } + } + } + + public int Count + { + get { return _sessionRecords.Values.Select(q => q.Count).Sum(); } + } + + public void EnqueueRange(List records) + { + foreach (RecordEntry recordEntry in records) + { + Enqueue(recordEntry); + } + } + } +} diff --git a/tools/TestFx/Recorder/RequestResponseInfo.cs b/tools/TestFx/Recorder/RequestResponseInfo.cs new file mode 100644 index 000000000000..ab2bfaebd1e0 --- /dev/null +++ b/tools/TestFx/Recorder/RequestResponseInfo.cs @@ -0,0 +1,267 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + public class RequestResponseInfo + { + public RecordEntry InternalRecordEntry { get; internal set; } + + public LongRunningOperationInfo LroInfo { get; internal set; } + + public RequestResponseInfo(RecordEntry entry) + { + InternalRecordEntry = entry; + LroInfo = new LongRunningOperationInfo(entry); + } + } + + public class LongRunningOperationInfo + { + const string perfImpactKey = "RecordPlaybackPerfImpact"; + + const string operationKey = "LroOperation"; + + public string OperationVerb { get; internal set; } + + public bool IsPlaybackPerfImpacted { get; internal set; } + + public LROHeaderInfo LroHeader { get; internal set; } + + public LroInfoId LroId { get; internal set; } + + public LongRunningOperationInfo(RecordEntry entry) + { + IsPlaybackPerfImpacted = false; + + LroHeader = new LROHeaderInfo(entry.RequestHeaders); + InitDataFromHeaders(entry.RequestHeaders); + LroId = new LroInfoId(entry.RequestHeaders); + } + + void InitDataFromHeaders(Dictionary> headers) + { + foreach (KeyValuePair> kv in headers) + { + if (kv.Key.Equals(operationKey, StringComparison.OrdinalIgnoreCase)) + { + OperationVerb = kv.Value?.SingleOrDefault(); + } + + if (kv.Key.Equals(perfImpactKey, StringComparison.OrdinalIgnoreCase)) + { + IsPlaybackPerfImpacted = Convert.ToBoolean(kv.Value?.SingleOrDefault()); + } + } + } + } + + public class LroInfoId + { + const string sessionIdKey = "LroSessionId"; + + const string sessionPollingIdKey = "LroPollingId"; + + private string internalSessionPollingId { get; set; } + + public long SessionId { get; internal set; } + + public long PollingId { get; internal set; } + + public int PollingCount { get; internal set; } + + public LroInfoId(Dictionary> headers) + { + SessionId = 0; + PollingId = 0; + PollingCount = 0; + DeconstructSessionPollingId(headers); + } + + void DeconstructSessionPollingId(Dictionary> headers) + { + foreach (KeyValuePair> kv in headers) + { + if (kv.Key.Equals(sessionIdKey, StringComparison.OrdinalIgnoreCase)) + { + SessionId = Convert.ToInt64(kv.Value?.SingleOrDefault()); + } + + if (kv.Key.Equals(sessionPollingIdKey, StringComparison.OrdinalIgnoreCase)) + { + internalSessionPollingId = kv.Value?.Single(); + } + } + + if (!string.IsNullOrEmpty(internalSessionPollingId)) + { + string[] sessionPollingTokens = internalSessionPollingId.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + + if (sessionPollingTokens != null) + { + if (sessionPollingTokens.Length == 3) + { + PollingId = Convert.ToInt64(sessionPollingTokens[1]); + PollingCount = Convert.ToInt32(sessionPollingTokens[2]); + } + } + } + } + + public static bool operator >(LroInfoId lhId, LroInfoId rhId) + { + bool greaterThan; + + if ((lhId.SessionId > rhId.SessionId) && + (lhId.PollingId > rhId.PollingId) && + (lhId.PollingCount > rhId.PollingCount)) + { + greaterThan = true; + } + else if ((lhId.SessionId == rhId.SessionId) && + (lhId.PollingId > rhId.PollingId) && + (lhId.PollingCount > rhId.PollingCount)) + { + greaterThan = true; + } + else if ((lhId.SessionId == rhId.SessionId) && + (lhId.PollingId == rhId.PollingId) && + (lhId.PollingCount > rhId.PollingCount)) + { + greaterThan = true; + } + else + greaterThan = false; + + return greaterThan; + } + + public static bool operator <(LroInfoId lhId, LroInfoId rhId) + { + bool lessThan; + + if ((lhId.SessionId < rhId.SessionId) && + (lhId.PollingId < rhId.PollingId) && + (lhId.PollingCount < rhId.PollingCount)) + { + lessThan = true; + } + else if ((lhId.SessionId == rhId.SessionId) && + (lhId.PollingId < rhId.PollingId) && + (lhId.PollingCount < rhId.PollingCount)) + { + lessThan = true; + } + else if ((lhId.SessionId == rhId.SessionId) && + (lhId.PollingId == rhId.PollingId) && + (lhId.PollingCount < rhId.PollingCount)) + { + lessThan = true; + } + else + lessThan = false; + + return lessThan; + } + + public override string ToString() + { + return internalSessionPollingId; + } + } + + public class LROHeaderInfo + { + const string LocHeaderKey = "Location"; + const string AzAsyncHeaderKey = "Azure-AsyncOperation"; + + public string LocationHeader { get; private set; } + + public string AzureAsyncOperationHeader { get; private set; } + + private LroHeaderKind HeaderKind { get; set; } + + public LROHeaderInfo(Dictionary> headers) + { + LocationHeader = string.Empty; + AzureAsyncOperationHeader = string.Empty; + + foreach (KeyValuePair> kv in headers) + { + if (kv.Key.Equals(LocHeaderKey, StringComparison.OrdinalIgnoreCase)) + { + LocationHeader = kv.Value?.FirstOrDefault(); + } + + if (kv.Key.Equals(AzAsyncHeaderKey, StringComparison.OrdinalIgnoreCase)) + { + AzureAsyncOperationHeader = kv.Value?.FirstOrDefault(); + } + } + + UpdateHeaderKind(); + } + + private void UpdateHeaderKind() + { + bool validLoc = false, validAzAsync = false; + + if (IsValidUri(LocationHeader)) + { + validLoc = true; + HeaderKind = LroHeaderKind.Location; + } + + if (IsValidUri(AzureAsyncOperationHeader)) + { + validAzAsync = true; + HeaderKind = LroHeaderKind.AzureAsync; + } + + if (validLoc && validAzAsync) + HeaderKind = LroHeaderKind.Location_AzureAsync; + } + + private Uri GetValidUri(string uriString) + { + Uri validUri = null; + try + { + validUri = new Uri(uriString); + } + catch { } + + return validUri; + } + + private bool IsValidUri(string uriString) + { + if (GetValidUri(uriString) == null) + return false; + + return true; + } + + public enum LroHeaderKind + { + Location, + AzureAsync, + Location_AzureAsync + } + } +} diff --git a/tools/TestFx/Recorder/SimpleRecordMatcher.cs b/tools/TestFx/Recorder/SimpleRecordMatcher.cs new file mode 100644 index 000000000000..f79f724c4c31 --- /dev/null +++ b/tools/TestFx/Recorder/SimpleRecordMatcher.cs @@ -0,0 +1,79 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; + +namespace Microsoft.Azure.Commands.TestFx.Recorder +{ + /// + /// This class does a simple mapping between given request and responses. + /// The hashing algorithm works by combining the HTTP method of the request + /// plus the request uri together. Optionally a key-value pair of headers + /// can be added to the key. + /// + public class SimpleRecordMatcher : IRecordMatcher + { + public HashSet MatchingHeaders { get; private set; } + + public SimpleRecordMatcher() + { + MatchingHeaders = new HashSet(StringComparer.OrdinalIgnoreCase); + } + + public SimpleRecordMatcher(params string[] matchingHeaders) + { + MatchingHeaders = new HashSet(matchingHeaders, StringComparer.OrdinalIgnoreCase); + } + + private string GetMatchingKey(string httpMethod, string requestUri, Dictionary> requestHeaders) + { + StringBuilder key = new StringBuilder(string.Format("{0} {1}", httpMethod, requestUri)); + + if (requestHeaders != null) + { + foreach (var requestHeader in requestHeaders.OrderBy(h => h.Key)) + { + if (MatchingHeaders.Contains(requestHeader.Key)) + { + key.AppendFormat(" ({0}={1})", requestHeader.Key, string.Join(",", requestHeader.Value)); + } + } + } + + return key.ToString(); + } + + public string GetMatchingKey(RecordEntry recordEntry) + { + return GetMatchingKey(recordEntry.RequestMethod, + (recordEntry.EncodedRequestUri ?? RecorderUtilities.EncodeUriAsBase64(recordEntry.RequestUri)), + recordEntry.RequestHeaders); + } + + public string GetMatchingKey(HttpRequestMessage request) + { + var requestHeaders = new Dictionary>(); + request.Headers.ForEach(h => requestHeaders.Add(h.Key, h.Value.ToList())); + if (request.Content != null) + { + request.Content.Headers.ForEach(h => requestHeaders.Add(h.Key, h.Value.ToList())); + } + return GetMatchingKey(request.Method.Method, RecorderUtilities.EncodeUriAsBase64(request.RequestUri), requestHeaders); + } + } +} diff --git a/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlansTestController.cs b/tools/TestFx/SubscriptionInfo.cs similarity index 52% rename from src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlansTestController.cs rename to tools/TestFx/SubscriptionInfo.cs index 78ffa86cff3c..899eed9ef7bf 100644 --- a/src/MachineLearning/MachineLearning.Test/ScenarioTests/CommitmentPlansTestController.cs +++ b/tools/TestFx/SubscriptionInfo.cs @@ -12,24 +12,26 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -using Microsoft.Azure.Management.MachineLearning.CommitmentPlans; +using Newtonsoft.Json.Linq; -namespace Microsoft.Azure.Commands.MachineLearning.Test.ScenarioTests +namespace Microsoft.Azure.Commands.TestFx { - public class CommitmentPlansTestController : BaseTestController + public class SubscriptionInfo { - public static CommitmentPlansTestController NewInstance + public SubscriptionInfo(JObject resultObject) { - get - { - return new CommitmentPlansTestController(); - } + Id = (string)(resultObject["id"]); + SubscriptionId = (string)(resultObject["subscriptionId"]); + DisplayName = (string)(resultObject["displayName"]); + State = (string)(resultObject["state"]); } - protected override AzureMLCommitmentPlansManagementClient ConstructServiceClient(MockContext context) - { - return context.GetServiceClient(TestEnvironmentFactory.GetTestEnvironment()); - } + public string Id { get; set; } + + public string SubscriptionId { get; set; } + + public string DisplayName { get; set; } + + public string State { get; set; } } } diff --git a/tools/TestFx/TestClientFactory.cs b/tools/TestFx/TestClientFactory.cs deleted file mode 100644 index 21e34010483f..000000000000 --- a/tools/TestFx/TestClientFactory.cs +++ /dev/null @@ -1,147 +0,0 @@ -// ---------------------------------------------------------------------------------- -// -// Copyright Microsoft Corporation -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// http://www.apache.org/licenses/LICENSE-2.0 -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// ---------------------------------------------------------------------------------- - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net; -using System.Net.Http; -using System.Net.Http.Headers; -using Microsoft.Azure.Commands.Common.Authentication; -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -using Microsoft.Azure.Commands.Common.Authentication.Models; -using Microsoft.Rest.ClientRuntime.Azure.TestFramework; -#if NETSTANDARD -using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Core; -#endif - -namespace Microsoft.Azure.Commands.TestFx -{ - public class TestClientFactory : IClientFactory - { - private readonly MockContext _mockContext; - - public TestClientFactory(MockContext mockContext) - { - _mockContext = mockContext ?? throw new ArgumentNullException(nameof(mockContext)); - } - - public TClient CreateArmClient(IAzureContext context, string endpoint) where TClient : Rest.ServiceClient - { - return string.Equals(endpoint, AzureEnvironment.Endpoint.Graph, StringComparison.OrdinalIgnoreCase) ? - _mockContext.GetGraphServiceClient() : - _mockContext.GetServiceClient(); - } - - public TClient CreateCustomArmClient(params object[] parameters) where TClient : Rest.ServiceClient - { - return _mockContext.GetServiceClient(); - } - - public HttpClient CreateHttpClient(string endpoint, ICredentials credentials) - { - throw new NotImplementedException(); - } - - public HttpClient CreateHttpClient(string endpoint, HttpMessageHandler effectiveHandler) - { - throw new NotImplementedException(); - } - - #region Action and Handler - - public void AddAction(IClientAction action) - { - // Do nothing - } - - public void RemoveAction(Type actionType) - { - // Do nothing - } - - public void AddHandler(T handler) where T : DelegatingHandler, ICloneable - { - // Do nothing - } - - public void RemoveHandler(Type handlerType) - { - // Do nothing - } - public DelegatingHandler[] GetCustomHandlers() - { - // Do nothing - return new DelegatingHandler[0]; - } - - #endregion - - #region UserAgent - - public HashSet UniqueUserAgents { get; set; } = new HashSet(); - - public void AddUserAgent(string productName, string productVersion) - { - if(string.IsNullOrEmpty(productName)) - { - return; - } - if(string.IsNullOrEmpty(productVersion)) - { - productVersion = ""; - } - UniqueUserAgents.Add(new ProductInfoHeaderValue(productName, productVersion)); - } - - public void AddUserAgent(string productName) - { - AddUserAgent(productName, ""); - } - - public void RemoveUserAgent(string name) - { - UniqueUserAgents.RemoveWhere(p => string.Equals(p.Product.Name, name, StringComparison.OrdinalIgnoreCase)); - } - - public ProductInfoHeaderValue[] UserAgents => UniqueUserAgents.ToArray(); - - #endregion - - #region Hyak - - public TClient CreateClient(IAzureContext context, string endpoint) where TClient : Hyak.Common.ServiceClient - { - throw new NotImplementedException(); - } - - public TClient CreateClient(IAzureContextContainer profile, string endpoint) where TClient : Hyak.Common.ServiceClient - { - throw new NotImplementedException(); - } - - public TClient CreateClient(IAzureContextContainer profile, IAzureSubscription subscription, string endpoint) where TClient : Hyak.Common.ServiceClient - { - throw new NotImplementedException(); - } - - public TClient CreateCustomClient(params object[] parameters) where TClient : Hyak.Common.ServiceClient - { - throw new NotImplementedException(); - } - - #endregion - - } -} diff --git a/tools/ScenarioTest.ResourceManager/Constants.cs b/tools/TestFx/TestConstants.cs similarity index 79% rename from tools/ScenarioTest.ResourceManager/Constants.cs rename to tools/TestFx/TestConstants.cs index 5cbe95b8911a..30a2496d075d 100644 --- a/tools/ScenarioTest.ResourceManager/Constants.cs +++ b/tools/TestFx/TestConstants.cs @@ -1,5 +1,4 @@ - -// ---------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------- // // Copyright Microsoft Corporation // Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,11 +12,31 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +namespace Microsoft.Azure.Commands.TestFx +{ + public enum TestEnvironmentName + { + Prod, + Dogfood, + Next, + Current, + Custom + } + + public class Variables + { + public const string SubscriptionId = "SubscriptionId"; + + public const string TenantId = "TenantId"; + + public const string Username = "Username"; + } +} + namespace Microsoft.WindowsAzure.Commands.ScenarioTest { public class Category { - // Service public const string Service = "Service"; public const string All = "All"; @@ -54,12 +73,10 @@ public class Category public const string Network = "Network"; - // Owners public const string Owner = "Owner"; public const string OneSDK = "OneSDK"; - // Acceptance type public const string AcceptanceType = "AcceptanceType"; public const string CIT = "CIT"; @@ -67,33 +84,33 @@ public class Category public const string BVT = "BVT"; public const string CheckIn = "CheckIn"; - + public const string Flaky = "Flaky"; - // Run Type public const string RunType = "RunType"; - // Run types to select by edition public const string CoreOnly = "CoreOnly"; + public const string DesktopOnly = "DesktopOnly"; public const string LiveOnly = "LiveOnly"; - //Uncomment when we need to tag on only run under mock - //public const string MockedOnly = "MockedOnly"; - - // Environment public const string Environment = "Environment"; public const string WAPack = "WAPack"; } +} - public class Variables +namespace Microsoft.Rest.ClientRuntime.Azure.TestFramework +{ + public static class TestTraits { - public const string SubscriptionId = "SubscriptionId"; + public const string AcceptanceType = "AcceptanceType"; - public const string Username = "Username"; + public const string CheckIn = "CheckIn"; + + public const string LiveBVT = "LiveBVT"; - public const string Tenantd = "Tenantd"; + public const string MockedBVT = "MockedBVT"; } } diff --git a/tools/TestFx/TestEndpoints.cs b/tools/TestFx/TestEndpoints.cs new file mode 100644 index 000000000000..deabac33fb99 --- /dev/null +++ b/tools/TestFx/TestEndpoints.cs @@ -0,0 +1,207 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; + +namespace Microsoft.Azure.Commands.TestFx +{ + public class TestEndpoints + { + public TestEnvironmentName Name { get; set; } + + public Uri ServiceManagementUri { get; set; } + + public Uri ResourceManagementUri { get; set; } + + public Uri AADAuthUri { get; set; } + + public Uri AADTokenAudienceUri { get; set; } + + public Uri GraphUri { get; set; } + + public Uri GraphTokenAudienceUri { get; set; } + + public Uri GalleryUri { get; set; } + + public Uri RdfePortalUri { get; set; } + + public Uri IbizaPortalUri { get; set; } + + public Uri DataLakeStoreServiceUri { get; set; } + + public Uri DataLakeAnalyticsJobAndCatalogServiceUri { get; set; } + + public Uri PublishingSettingsFileUri { get; set; } + + private TestEndpoints() + { + + } + + internal TestEndpoints(TestEndpoints testEndpoint, ConnectionString connStr) : this(testEndpoint) + { + UpdateEnvironmentEndpoint(connStr); + } + + private void UpdateEnvironmentEndpoint(ConnectionString connStr) + { + if (connStr.HasNonEmptyValue(ConnectionStringKeys.AADTokenAudienceUriKey)) + { + AADTokenAudienceUri = new Uri(connStr.GetValue(ConnectionStringKeys.AADTokenAudienceUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.GraphTokenAudienceUriKey)) + { + GraphTokenAudienceUri = new Uri(connStr.GetValue(ConnectionStringKeys.GraphTokenAudienceUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.GraphUriKey)) + { + GraphUri = new Uri(connStr.GetValue(ConnectionStringKeys.GraphUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.GalleryUriKey)) + { + GalleryUri = new Uri(connStr.GetValue(ConnectionStringKeys.GalleryUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.IbizaPortalUriKey)) + { + IbizaPortalUri = new Uri(connStr.GetValue(ConnectionStringKeys.IbizaPortalUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.RdfePortalUriKey)) + { + RdfePortalUri = new Uri(connStr.GetValue(ConnectionStringKeys.RdfePortalUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.DataLakeStoreServiceUriKey)) + { + DataLakeStoreServiceUri = new Uri(connStr.GetValue(ConnectionStringKeys.DataLakeStoreServiceUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.DataLakeAnalyticsJobAndCatalogServiceUriKey)) + { + DataLakeAnalyticsJobAndCatalogServiceUri = new Uri(connStr.GetValue(ConnectionStringKeys.DataLakeAnalyticsJobAndCatalogServiceUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.AADAuthUriKey)) + { + AADAuthUri = new Uri(connStr.GetValue(ConnectionStringKeys.AADAuthUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.PublishSettingsFileUriKey)) + { + PublishingSettingsFileUri = new Uri(connStr.GetValue(ConnectionStringKeys.PublishSettingsFileUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.ServiceManagementUriKey)) + { + ServiceManagementUri = new Uri(connStr.GetValue(ConnectionStringKeys.ServiceManagementUriKey)); + } + + if (connStr.HasNonEmptyValue(ConnectionStringKeys.ResourceManagementUriKey)) + { + ResourceManagementUri = new Uri(connStr.GetValue(ConnectionStringKeys.ResourceManagementUriKey)); + } + } + + internal TestEndpoints(TestEnvironmentName testEnvNames) + { + string defaultAADTokenAudienceUri = "https://management.core.windows.net/"; + string defaultGraphTokenAudienceUri = "https://graph.windows.net/"; + string defaultPPEGraphTokenAudienceUri = "https://graph.ppe.windows.net/"; + + switch (testEnvNames) + { + case TestEnvironmentName.Prod: + Name = TestEnvironmentName.Prod; + GraphUri = new Uri("https://graph.windows.net/"); + AADAuthUri = new Uri("https://login.microsoftonline.com/"); + GalleryUri = new Uri("https://gallery.azure.com/"); + IbizaPortalUri = new Uri("https://portal.azure.com/"); + RdfePortalUri = new Uri("https://manage.windowsazure.com/"); + ResourceManagementUri = new Uri("https://management.azure.com/"); + ServiceManagementUri = new Uri("https://management.core.windows.net"); + AADTokenAudienceUri = new Uri(defaultAADTokenAudienceUri); + GraphTokenAudienceUri = new Uri(defaultGraphTokenAudienceUri); + DataLakeStoreServiceUri = new Uri("https://azuredatalakestore.net"); + DataLakeAnalyticsJobAndCatalogServiceUri = new Uri("https://azuredatalakeanalytics.net"); + break; + case TestEnvironmentName.Dogfood: + Name = TestEnvironmentName.Dogfood; + GraphUri = new Uri("https://graph.ppe.windows.net/"); + AADAuthUri = new Uri("https://login.windows-ppe.net"); + GalleryUri = new Uri("https://df.gallery.azure-test.net/"); + IbizaPortalUri = new Uri("http://df.onecloud.azure-test.net"); + RdfePortalUri = new Uri("https://windows.azure-test.net"); + ResourceManagementUri = new Uri("https://api-dogfood.resources.windows-int.net/"); + ServiceManagementUri = new Uri("https://management-preview.core.windows-int.net"); + AADTokenAudienceUri = new Uri(defaultAADTokenAudienceUri); + GraphTokenAudienceUri = new Uri(defaultPPEGraphTokenAudienceUri); + DataLakeStoreServiceUri = new Uri("https://caboaccountdogfood.net"); + DataLakeAnalyticsJobAndCatalogServiceUri = new Uri("https://konaaccountdogfood.net"); + break; + case TestEnvironmentName.Next: + Name = TestEnvironmentName.Next; + GalleryUri = new Uri("https://next.gallery.azure-test.net/"); + AADAuthUri = new Uri("https://login.windows-ppe.net"); + GraphUri = new Uri("https://graph.ppe.windows.net/"); + IbizaPortalUri = new Uri("http://next.onecloud.azure-test.net"); + RdfePortalUri = new Uri("https://auxnext.windows.azure-test.net"); + ResourceManagementUri = new Uri("https://api-next.resources.windows-int.net/"); + ServiceManagementUri = new Uri("https://managementnext.rdfetest.dnsdemo4.com"); + AADTokenAudienceUri = new Uri(defaultAADTokenAudienceUri); + GraphTokenAudienceUri = new Uri(defaultPPEGraphTokenAudienceUri); + DataLakeStoreServiceUri = new Uri("https://caboaccountdogfood.net"); + DataLakeAnalyticsJobAndCatalogServiceUri = new Uri("https://konaaccountdogfood.net"); + break; + case TestEnvironmentName.Current: + Name = TestEnvironmentName.Current; + GalleryUri = new Uri("https://current.gallery.azure-test.net/"); + AADAuthUri = new Uri("https://login.windows-ppe.net"); + GraphUri = new Uri("https://graph.ppe.windows.net/"); + IbizaPortalUri = new Uri("http://current.onecloud.azure-test.net"); + RdfePortalUri = new Uri("https://auxcurrent.windows.azure-test.net"); + ResourceManagementUri = new Uri("https://api-current.resources.windows-int.net/"); + ServiceManagementUri = new Uri("https://management.rdfetest.dnsdemo4.com"); + AADTokenAudienceUri = new Uri(defaultAADTokenAudienceUri); + GraphTokenAudienceUri = new Uri(defaultPPEGraphTokenAudienceUri); + DataLakeStoreServiceUri = new Uri("https://caboaccountdogfood.net"); + DataLakeAnalyticsJobAndCatalogServiceUri = new Uri("https://konaaccountdogfood.net"); + break; + case TestEnvironmentName.Custom: + Name = TestEnvironmentName.Custom; + break; + } + } + + private TestEndpoints(TestEndpoints testEndpoint) + { + Name = testEndpoint.Name; + GraphUri = testEndpoint.GraphUri; + AADAuthUri = testEndpoint.AADAuthUri; + GalleryUri = testEndpoint.GalleryUri; + IbizaPortalUri = testEndpoint.IbizaPortalUri; + RdfePortalUri = testEndpoint.RdfePortalUri; + ResourceManagementUri = testEndpoint.ResourceManagementUri; + ServiceManagementUri = testEndpoint.ServiceManagementUri; + AADTokenAudienceUri = testEndpoint.AADTokenAudienceUri; + GraphTokenAudienceUri = testEndpoint.GraphTokenAudienceUri; + DataLakeStoreServiceUri = testEndpoint.DataLakeStoreServiceUri; + DataLakeAnalyticsJobAndCatalogServiceUri = testEndpoint.DataLakeAnalyticsJobAndCatalogServiceUri; + PublishingSettingsFileUri = testEndpoint.PublishingSettingsFileUri; + } + } +} diff --git a/tools/TestFx/TestEnvironment.cs b/tools/TestFx/TestEnvironment.cs new file mode 100644 index 000000000000..4cfb029e0d4d --- /dev/null +++ b/tools/TestFx/TestEnvironment.cs @@ -0,0 +1,427 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Test.HttpRecorder; +using Microsoft.Rest; +using Microsoft.Rest.Azure.Authentication; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.Commands.TestFx +{ + public class TestEnvironment + { + /// + /// Base Uri used by the Test Environment + /// + public Uri BaseUri { get; set; } + + /// + /// Base Azure Graph Uri used by the Test Environment + /// + public Uri GraphUri { get; set; } + + /// + /// UserName used by the Test Environment + /// + public string UserName { get; set; } + + /// + /// Tenant used by the Test Environment + /// + public string TenantId { get; set; } + + /// + /// Subscription Id used by the Test Environment + /// + public string SubscriptionId { get; set; } + + /// + /// Active TestEndpoint being used by the Test Environment + /// + public TestEndpoints Endpoints { get; set; } + + /// + /// Holds default endpoints for all the supported environments + /// + public IDictionary EnvEndpoints; + + /// + /// Connection string used by Test Environment + /// + public ConnectionString ConnectionString { get; private set; } + + /// + /// Credential dictionary to hold credentials for Management and Graph client + /// + public Dictionary TokenInfo { get; private set; } + + [DefaultValue(false)] + public bool OptimizeRecordedFile { get; set; } + + public TestEnvironment(string connectionString) + { + ConnectionString = new ConnectionString(connectionString); + InitTestEndPoints(); + + SubscriptionId = ConnectionString.GetValue(ConnectionStringKeys.SubscriptionIdKey); + TenantId = ConnectionString.GetValue(ConnectionStringKeys.TenantIdKey); + UserName = ConnectionString.GetValue(ConnectionStringKeys.UserIdKey); + OptimizeRecordedFile = ConnectionString.GetValue(ConnectionStringKeys.OptimizeRecordedFileKey); + + if (string.IsNullOrEmpty(ConnectionString.GetValue(ConnectionStringKeys.BaseUriKey))) + { + BaseUri = Endpoints.ResourceManagementUri; + } + else + { + BaseUri = new Uri(ConnectionString.GetValue(ConnectionStringKeys.BaseUriKey)); + } + + if (string.IsNullOrWhiteSpace(ConnectionString.GetValue(ConnectionStringKeys.GraphUriKey))) + { + GraphUri = Endpoints.GraphUri; + } + else if (!string.IsNullOrWhiteSpace(ConnectionString.GetValue(ConnectionStringKeys.GraphUriKey))) + { + GraphUri = new Uri(ConnectionString.GetValue(ConnectionStringKeys.GraphUriKey)); + } + + InitTokenDictionary(); + SetupHttpRecorderMode(); + RecorderModeSettings(); + } + + private void InitTestEndPoints() + { + LoadDefaultEnvironmentEndpoints(); + string envNameString = ConnectionString.GetValue(ConnectionStringKeys.EnvironmentKey); + if (!string.IsNullOrEmpty(envNameString)) + { + envNameString = nameof(TestEnvironmentName.Prod); + } + + Enum.TryParse(envNameString, true, out TestEnvironmentName envName); + Endpoints = new TestEndpoints(EnvEndpoints[envName], ConnectionString); + + } + + private void LoadDefaultEnvironmentEndpoints() + { + if (EnvEndpoints == null) + { + EnvEndpoints = new Dictionary() + { + { TestEnvironmentName.Prod, new TestEndpoints(TestEnvironmentName.Prod) }, + { TestEnvironmentName.Dogfood, new TestEndpoints(TestEnvironmentName.Dogfood) }, + { TestEnvironmentName.Next, new TestEndpoints(TestEnvironmentName.Next) }, + { TestEnvironmentName.Current, new TestEndpoints(TestEnvironmentName.Current) }, + { TestEnvironmentName.Custom, new TestEndpoints(TestEnvironmentName.Custom) } + }; + } + } + + private void InitTokenDictionary() + { + TokenInfo = new Dictionary(); + + ConnectionString.KeyValuePairs.TryGetValue(ConnectionStringKeys.RawTokenKey, out string rawToken); + ConnectionString.KeyValuePairs.TryGetValue(ConnectionStringKeys.RawGraphTokenKey, out string rawGraphToken); + + // We need TokenInfo to be non-empty as there are cases where have taken dependency on non-empty TokenInfo in MockContext + if (string.IsNullOrEmpty(rawToken)) + { + rawToken = ConnectionStringKeys.RawTokenKey; + } + + if (string.IsNullOrEmpty(rawGraphToken)) + { + rawGraphToken = ConnectionStringKeys.RawGraphTokenKey; + } + + TokenInfo[TokenAudience.Management] = new TokenCredentials(rawToken); + TokenInfo[TokenAudience.Graph] = new TokenCredentials(rawGraphToken); + } + + private void SetupHttpRecorderMode() + { + string testMode = Environment.GetEnvironmentVariable(ConnectionStringKeys.AZURE_TEST_MODE_ENVKEY); + + if (string.IsNullOrEmpty(testMode)) + { + testMode = ConnectionString.GetValue(ConnectionStringKeys.HttpRecorderModeKey); + } + + // Ideally we should be throwing when incompatible environment (e.g. Environment=Foo) is provided in connection string + // But currently we do not throw + if (Enum.TryParse(testMode, out HttpRecorderMode recorderMode)) + { + HttpMockServer.Mode = recorderMode; + } + else + { + // Log incompatible recorder mode + // Currently we set Playback as default recorder mode + HttpMockServer.Mode = HttpRecorderMode.Playback; + } + } + + private void RecorderModeSettings() + { + if (HttpMockServer.Mode == HttpRecorderMode.Playback) + { + //Get Subscription Id from MockServer + if (HttpMockServer.Variables.ContainsCaseInsensitiveKey(ConnectionStringKeys.SubscriptionIdKey)) + { + SubscriptionId = HttpMockServer.Variables.GetValueUsingCaseInsensitiveKey(ConnectionStringKeys.SubscriptionIdKey); + } + else if (string.IsNullOrEmpty(SubscriptionId)) + { + throw new Exception($"Subscription Id is not present in the recorded mock or in connection string (e.g. {ConnectionStringKeys.SubscriptionIdKey}=)"); + } + } + else if (HttpMockServer.Mode == HttpRecorderMode.Record) + { + //Restore/Add Subscription Id in MockServer from supplied connection string + if (HttpMockServer.Variables.ContainsCaseInsensitiveKey(ConnectionStringKeys.SubscriptionIdKey)) + { + HttpMockServer.Variables.UpdateDictionary(ConnectionStringKeys.SubscriptionIdKey, SubscriptionId); + } + else + { + HttpMockServer.Variables.Add(ConnectionStringKeys.SubscriptionIdKey, SubscriptionId); + } + + // If User has provided Access Token in RawToken/GraphToken Key-Value, we don't need to authenticate + // We currently only check for RawToken and do not check if GraphToken is provided + if (string.IsNullOrEmpty(ConnectionString.GetValue(ConnectionStringKeys.RawTokenKey))) + { + Login(); + } + + VerifyAuthTokens(); + } + } + + private void Login() + { + string userPassword = ConnectionString.GetValue(ConnectionStringKeys.PasswordKey); + string spnClientId = ConnectionString.GetValue(ConnectionStringKeys.ServicePrincipalKey); + string spnClientSecret = ConnectionString.GetValue(ConnectionStringKeys.ServicePrincipalSecretKey); + //We use this because when login silently using userTokenProvider, we need to provide a well known ClientId for an app that has delegating permissions. + //All first party app have that permissions, so we use PowerShell app ClientId +#if net452 + string PowerShellClientId = "1950a258-227b-4e31-a9cf-717495945fc2"; +#endif + /* + * Currently we prioritize login as below: + * 1) ServicePrincipal/ServicePrincipal Secret Key + * 2) UserName / Password combination + * 3) Interactive Login (where user will be presented with prompt to login) + */ + + ActiveDirectoryServiceSettings aadServiceSettings = new ActiveDirectoryServiceSettings() + { + AuthenticationEndpoint = new Uri(Endpoints.AADAuthUri.ToString() + ConnectionString.GetValue(ConnectionStringKeys.TenantIdKey)), + TokenAudience = Endpoints.AADTokenAudienceUri + }; + + ActiveDirectoryServiceSettings graphAADServiceSettings = new ActiveDirectoryServiceSettings() + { + AuthenticationEndpoint = new Uri(Endpoints.AADAuthUri.ToString() + ConnectionString.GetValue(ConnectionStringKeys.TenantIdKey)), + TokenAudience = Endpoints.GraphTokenAudienceUri + }; + + if ((!string.IsNullOrEmpty(spnClientId)) && (!string.IsNullOrEmpty(spnClientSecret))) + { + Task mgmAuthResult = Task.Run(async () => (TokenCredentials)await ApplicationTokenProvider.LoginSilentAsync(TenantId, spnClientId, spnClientSecret, aadServiceSettings).ConfigureAwait(false)); + TokenInfo[TokenAudience.Management] = mgmAuthResult.Result; + UpdateTokenInfoWithGraphToken(graphAADServiceSettings, spnClientId: spnClientId, spnClientSecret: spnClientSecret); + } + else if ((!string.IsNullOrEmpty(UserName)) && (!string.IsNullOrEmpty(userPassword))) + { + //#if FullNetFx +#if net452 + Task mgmAuthResult = Task.Run(async () => (TokenCredentials)await UserTokenProvider.LoginSilentAsync(PowerShellClientId, TenantId, UserName, userPassword, aadServiceSettings).ConfigureAwait(false)); + this.TokenInfo[TokenAudience.Management] = mgmAuthResult.Result; + UpdateTokenInfoWithGraphToken(graphAADServiceSettings, userName: UserName, password: userPassword, psClientId: PowerShellClientId); +#else + throw new NotSupportedException("Username/Password login is supported only in NET452 and above projects"); +#endif + } + else + { + //#if FullNetFx +#if net452 + InteractiveLogin(TenantId, PowerShellClientId, aadServiceSettings, graphAADServiceSettings); +#else + throw new NotSupportedException("Interactive Login is supported only in NET452 and above projects"); +#endif + } + } + + private void UpdateTokenInfoWithGraphToken(ActiveDirectoryServiceSettings graphAADServiceSettings, string spnClientId = "", string spnClientSecret = "", string userName = "", string password = "", string psClientId = "") + { + Task graphAuthResult = null; + try + { + if (!string.IsNullOrWhiteSpace(userName) && !string.IsNullOrWhiteSpace(password)) + { + //#if FullNetFx +#if net452 + graphAuthResult = Task.Run(async () => (TokenCredentials)await UserTokenProvider.LoginSilentAsync(psClientId, TenantId, userName, password, graphAADServiceSettings).ConfigureAwait(false)); +#endif + } + else if (!string.IsNullOrWhiteSpace(spnClientId) && !string.IsNullOrWhiteSpace(spnClientSecret)) + { + graphAuthResult = Task.Run(async () => (TokenCredentials)await ApplicationTokenProvider.LoginSilentAsync(TenantId, spnClientId, spnClientSecret, graphAADServiceSettings).ConfigureAwait(false)); + } + + TokenInfo[TokenAudience.Graph] = graphAuthResult?.Result; + } + catch (Exception ex) + { + Debug.WriteLine($"Error while acquiring Graph Token: '{ex}'"); + // Not all accounts are registered to have access to Graph endpoints. + } + } + + private void VerifyAuthTokens() + { + VerifySubscription(); + VerifyGraphToken(); + } + + private void VerifySubscription() + { + string matchedSubscriptionId = string.Empty; + StringBuilder sb = new StringBuilder(); + string callerId = string.Empty; + string subs = string.Empty; + List subscriptionList = new List(); + + if (TokenInfo[TokenAudience.Management] != null) + { + subscriptionList = ListSubscriptions(BaseUri.ToString(), TokenInfo[TokenAudience.Management]); + try { callerId = TokenInfo[TokenAudience.Management].CallerId; } catch { } + } + + if (!(string.IsNullOrEmpty(SubscriptionId)) && !(SubscriptionId.Equals("None", StringComparison.OrdinalIgnoreCase))) + { + if (subscriptionList.Any()) + { + var matchedSubs = subscriptionList.Where(sub => sub.SubscriptionId.Equals(SubscriptionId, StringComparison.OrdinalIgnoreCase)).FirstOrDefault(); + if (matchedSubs != null) + { + matchedSubscriptionId = matchedSubs.SubscriptionId; + } + else + { + foreach (var subInfo in subscriptionList) + { + subs += subInfo.SubscriptionId + ","; + } + } + } + + if (string.IsNullOrEmpty(matchedSubscriptionId)) + { + sb.AppendLine($"SubscriptionList:'{subs}' retrieved for the user/spn id '{callerId}', do not match with the provided subscriptionId '{SubscriptionId}' in connection string"); + throw new Exception(sb.ToString()); + } + } + else + { + // The idea is in case if no match was found, we check if subscription Id was provided in connection string, if not + // we then check if the retrieved subscription list has exactly 1 subscription, if yes we will just use that one. + if (string.IsNullOrEmpty(SubscriptionId)) + { + if (subscriptionList.Count() == 1) + { + ConnectionString.KeyValuePairs[ConnectionStringKeys.SubscriptionIdKey] = subscriptionList.First().SubscriptionId; + } + else + { + if (string.IsNullOrEmpty(SubscriptionId)) + { + sb.AppendLine("Retrieved subscription list has more than 1 subscription. Connection string has no subscription provided. Provide SubcriptionId info in connection string"); + throw new Exception(sb.ToString()); + } + } + } + else if (SubscriptionId.Equals("None", StringComparison.OrdinalIgnoreCase)) + { + sb.AppendLine($"'{ConnectionStringKeys.TestCSMOrgIdConnectionStringKey}': connection string contains subscriptionId as '{SubscriptionId}'"); + sb.AppendLine("Provide valid SubcriptionId info in connection string"); + throw new Exception(sb.ToString()); + } + } + } + + private List ListSubscriptions(string baseUri, TokenCredentials credentials) + { + var request = new HttpRequestMessage + { + RequestUri = new Uri($"{baseUri}/subscriptions?api-version=2014-04-01-preview") + }; + + HttpClient client = new HttpClient(); + credentials.ProcessHttpRequestAsync(request, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); + HttpResponseMessage response = client.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + + string jsonString = response.Content.ReadAsStringAsync().Result; + var jsonResult = JObject.Parse(jsonString); + return ((JArray)jsonResult["value"]).Select(item => new SubscriptionInfo((JObject)item)).ToList(); + } + + private void VerifyGraphToken() + { + if (TokenInfo[TokenAudience.Graph] != null) + { + try + { + string operationUrl = $@"{GraphUri}{TenantId}/users?$orderby=displayName&$top=25&api-version=1.6"; + TokenCredentials graphCredential = TokenInfo[TokenAudience.Graph]; + + var request = new HttpRequestMessage + { + RequestUri = new Uri(operationUrl) + }; + + HttpClient client = new HttpClient(); + graphCredential.ProcessHttpRequestAsync(request, CancellationToken.None).ConfigureAwait(false).GetAwaiter().GetResult(); + HttpResponseMessage response = client.SendAsync(request).Result; + response.EnsureSuccessStatusCode(); + + string jsonString = response.Content.ReadAsStringAsync().Result; + var jsonResult = JObject.Parse(jsonString); + } + catch (Exception ex) + { + string graphFailMessage = $@"Unable to make request to graph endpoint '{GraphUri}' using credentials provided within the connectionstring"; + Debug.WriteLine(graphFailMessage, ex.ToString()); + } + } + } + } +} diff --git a/tools/TestFx/TestEnvironmentFactory.cs b/tools/TestFx/TestEnvironmentFactory.cs new file mode 100644 index 000000000000..b35af3092892 --- /dev/null +++ b/tools/TestFx/TestEnvironmentFactory.cs @@ -0,0 +1,28 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using Microsoft.Azure.Commands.TestFx; +using System; + +namespace Microsoft.Azure.Commands.TestFx +{ + public static class TestEnvironmentFactory + { + public static TestEnvironment GetTestEnvironment() + { + string envStr = Environment.GetEnvironmentVariable(ConnectionStringKeys.TestCSMOrgIdConnectionStringKey); + return new TestEnvironment(envStr); + } + } +} diff --git a/tools/ScenarioTest.ResourceManager/TestExecutionHelpers.cs b/tools/TestFx/TestExecutionHelpers.cs similarity index 100% rename from tools/ScenarioTest.ResourceManager/TestExecutionHelpers.cs rename to tools/TestFx/TestExecutionHelpers.cs diff --git a/tools/TestFx/TestFx.csproj b/tools/TestFx/TestFx.csproj index 4506fde64762..38de763afbb1 100644 --- a/tools/TestFx/TestFx.csproj +++ b/tools/TestFx/TestFx.csproj @@ -12,7 +12,21 @@ - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + + @@ -20,6 +34,7 @@ + diff --git a/tools/TestFx/TestManager.cs b/tools/TestFx/TestManager.cs index 874a77338dd7..0003ab3cf22f 100644 --- a/tools/TestFx/TestManager.cs +++ b/tools/TestFx/TestManager.cs @@ -12,44 +12,54 @@ // limitations under the License. // ---------------------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Commands.ResourceManager.Common; +using Microsoft.Azure.Commands.TestFx.Mocks; +using Microsoft.Azure.Commands.TestFx.Recorder; using Microsoft.Azure.ServiceManagement.Common.Models; using Microsoft.Azure.Test.HttpRecorder; using Microsoft.Rest.ClientRuntime.Azure.TestFramework; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.WindowsAzure.Commands.ScenarioTest; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using Xunit; using Xunit.Abstractions; namespace Microsoft.Azure.Commands.TestFx { public delegate IRecordMatcher RecordMatcherDelegate (bool ignoreResourcesClient, Dictionary resourceProviders, Dictionary userAgentsToIgnore); - + public class TestManager : ITestRunnerFactory, ITestRunner { - private readonly string _callingClassName; - private string _projectSubfolderForTestsName = null; - private string _newPsScriptFilename = null; - private Dictionary _matcherExtraUserAgentsToIgnore; - private Dictionary _matcherNewUserAgentsToIgnore; - private Dictionary _matcherResourceProviders; - private Action _mockContextAction; - private Func[] _initializedManagementClients; protected EnvironmentSetupHelper Helper; - protected readonly List RmModules; - protected readonly List CommonPsScripts = new List(); - - protected RecordMatcherDelegate RecordMatcher { get; set; } - protected XunitTracingInterceptor Logger { get; set; } + private readonly string _testProjectPath; + private readonly string _callingClassName; + private string _testBaseFolderName = String.Empty; + private string _psTestScript; + private readonly List _psAzModules; + private readonly List _psCommonScripts = new List(); + + private RecordMatcherDelegate _recordMatcher; + private bool _matcherIgnoreResourceClient = true; + private Dictionary _matcherUserAgentsToIgnore; + private Dictionary _matcherResourceProvidersToIgnore; + + private Action _initAction; + private Action _mockContextAction; + private Action _cleanupAction; + + private Func[] _initializedServiceClients; + /// /// Factory method /// @@ -61,30 +71,27 @@ public static ITestRunnerFactory CreateInstance(ITestOutputHelper output, [Calle var callingClassName = string.IsNullOrEmpty(callerFilePath) ? null : Path.GetFileNameWithoutExtension(callerFilePath); - return new TestManager(callingClassName).WithTestOutputHelper(output); + + return new TestManager(callingClassName, Assembly.GetCallingAssembly()).WithTestOutputHelper(output); } /// /// ctor /// /// - protected TestManager(string callingClassName) + protected TestManager(string callingClassName, Assembly callingAssembly) { Helper = new EnvironmentSetupHelper(); _callingClassName = callingClassName; + _testProjectPath = GetTestProjectPath(callingAssembly); - RmModules = new List + _psAzModules = new List { Helper.RMProfileModule, Helper.RMResourceModule, }; - - RecordMatcher = (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => - new PermissiveRecordMatcherWithApiExclusion(ignoreResourcesClient, resourceProviders, userAgentsToIgnore); } - #region Builder impl - /// /// Sets a name of the subfolder where a test project keeps tests /// @@ -92,55 +99,55 @@ protected TestManager(string callingClassName) /// self public ITestRunnerFactory WithProjectSubfolderForTests(string folderName) { - _projectSubfolderForTestsName = folderName ?? "ScenarioTests"; + _testBaseFolderName = folderName ?? "ScenarioTests"; return this; } /// - /// Add helper scripts + /// Overrided default script name, which by convension is the cs test class name with ps1 extension. /// - /// + /// /// self - public ITestRunnerFactory WithCommonPsScripts(string[] psScriptList) + public ITestRunnerFactory WithNewPsScriptFilename(string psScriptName) { - CommonPsScripts.AddRange(psScriptList); + _psTestScript = psScriptName; return this; } /// - /// Overrided default script name, which by convension is the cs test class name with ps1 extension. + /// Add helper scripts /// - /// + /// /// self - public ITestRunnerFactory WithNewPsScriptFilename(string psScriptName) + public ITestRunnerFactory WithCommonPsScripts(string[] psScriptList) { - _newPsScriptFilename = psScriptName; + _psCommonScripts.AddRange(psScriptList); return this; } /// - /// Adds extra RM modules in addition to the RMProfileModule and RMResourceModule, - /// witch are added in the constructor. + /// Clears default RM modules list and sets a brand new /// /// /// - public ITestRunnerFactory WithExtraRmModules(Func buildModuleList) + public ITestRunnerFactory WithNewRmModules(Func buildModuleList) { + _psAzModules.Clear(); var moduleList = buildModuleList(Helper); - RmModules.AddRange(moduleList); + _psAzModules.AddRange(moduleList); return this; } /// - /// Clears default RM modules list and sets a brand new + /// Adds extra RM modules in addition to the RMProfileModule and RMResourceModule, + /// witch are added in the constructor. /// /// /// - public ITestRunnerFactory WithNewRmModules(Func buildModuleList) + public ITestRunnerFactory WithExtraRmModules(Func buildModuleList) { - RmModules.Clear(); var moduleList = buildModuleList(Helper); - RmModules.AddRange(moduleList); + _psAzModules.AddRange(moduleList); return this; } @@ -150,41 +157,40 @@ public ITestRunnerFactory WithNewRmModules(FuncDictionary [userAgent:apiVersion] to ignore /// Dictionary [resouceProvider:apiVersion] to match /// - public ITestRunnerFactory WithNewRecordMatcherArguments(Dictionary userAgentsToIgnore, Dictionary resourceProviders) + public ITestRunnerFactory WithNewRecordMatcherArguments(Dictionary userAgentsToIgnore, Dictionary resourceProviders, bool ignoreResourceClient = true) { - _matcherNewUserAgentsToIgnore = userAgentsToIgnore; - _matcherResourceProviders = resourceProviders; + _matcherIgnoreResourceClient = ignoreResourceClient; + _matcherUserAgentsToIgnore = userAgentsToIgnore; + _matcherResourceProvidersToIgnore = resourceProviders; return this; } - public ITestRunnerFactory WithMockContextAction(Action mockContextAction) + public ITestRunnerFactory WithInitAction(Action initAction) + { + _initAction = initAction; + return this; + } + + public ITestRunnerFactory WithMockContextAction(Action mockContextAction) { _mockContextAction = mockContextAction; return this; } - /// - /// Sets a new HttpMockServer.Matcher implementation. By defauls it's PermissiveRecordMatcherWithApiExclusion - /// - /// delegate - /// self - public ITestRunnerFactory WithRecordMatcher(RecordMatcherDelegate recordMatcher) + public ITestRunnerFactory WithCleanupAction(Action cleanupAction) { - RecordMatcher = recordMatcher; + _cleanupAction = cleanupAction; return this; } /// - /// WithExtraUserAgentsToIgnore + /// Sets a new HttpMockServer.Matcher implementation. By defauls it's PermissiveRecordMatcherWithApiExclusion /// - /// - /// Dictionary to store pairs: {user agent name, version-api to ignore}. - /// Initial pair is {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"} - /// + /// delegate /// self - public ITestRunnerFactory WithExtraUserAgentsToIgnore(Dictionary userAgentsToIgnore) + public ITestRunnerFactory WithRecordMatcher(RecordMatcherDelegate recordMatcher) { - _matcherExtraUserAgentsToIgnore = userAgentsToIgnore; + _recordMatcher = recordMatcher; return this; } @@ -198,66 +204,88 @@ public ITestRunnerFactory WithTestOutputHelper(ITestOutputHelper output) public ITestRunnerFactory WithManagementClients(params Func[] initializedManagementClients) { - _initializedManagementClients = initializedManagementClients; + _initializedServiceClients = initializedManagementClients; return this; } public ITestRunner Build() { SetupSessionAndProfile(); - SetupMockServerMatcher(); - HttpMockServer.RecordsDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SessionRecords"); + SetupMockServer(); Helper.SetupModules(AzureModule.AzureResourceManager, BuildModulesList()); return this; } public void RunTestScript(params string[] scripts) { - var sf = new StackTrace().GetFrame(1); - var className = sf.GetMethod().ReflectedType?.ToString(); - var methodName = sf.GetMethod().Name; + RunTestScriptCore(null, null, null, scripts); + } - using (var mockContext = MockContext.Start(className, methodName)) - { - _mockContextAction?.Invoke(); - AzureSession.Instance.ClientFactory = new TestClientFactory(mockContext); - SetupManagementClients(mockContext); - Helper.SetupEnvironment(AzureModule.AzureResourceManager); - SetupAzureContext(); - Helper.RunPowerShellTest(scripts); - } + public void RunTestScript(Action contextAction, params string[] scripts) + { + RunTestScriptCore(null, contextAction, null, scripts); } public void RunTestScript(Action setUp, Action tearDown, params string[] scripts) { + RunTestScriptCore(setUp, null, tearDown, scripts); + } + + public void RunTestScript(Action setUp, Action contextAction, Action tearDown, params string[] scripts) + { + RunTestScriptCore(setUp, contextAction, tearDown, scripts); + } + + private void RunTestScriptCore(Action setUp, Action contextAction, Action tearDown, params string[] scripts) + { + var sf = new StackTrace().GetFrame(2); + var method = sf.GetMethod(); + var className = method.ReflectedType?.ToString(); + var methodName = method.Name; + + _initAction?.Invoke(); setUp?.Invoke(); - RunTestScript(scripts); + + using var context = MockContext.Start(className, methodName); + _mockContextAction?.Invoke(context); + Helper.SetupEnvironment(AzureModule.AzureResourceManager); + SetupAzureContext(); + var serviceClients = SetupServiceClients(context); + AzureSession.Instance.ClientFactory = new MockClientFactory(context, serviceClients); + contextAction?.Invoke(context); + Helper.RunPowerShellTest(scripts); + tearDown?.Invoke(); + _cleanupAction?.Invoke(); } - #endregion + private string GetTestProjectPath(Assembly testAssembly) + { + var testProjectPath = testAssembly.GetCustomAttributes().Single(a => a.Key == "TestProjectPath")?.Value; - #region Helpers + if (string.IsNullOrEmpty(testProjectPath)) + { + throw new InvalidOperationException($"Unable to determine the test directory for {testAssembly}"); + } + + return testProjectPath; + } protected string[] BuildModulesList() { if (string.IsNullOrEmpty(_callingClassName) - && string.IsNullOrEmpty(_newPsScriptFilename)) - throw new ArgumentNullException($"Both {nameof(_callingClassName)} and {nameof(_newPsScriptFilename)} are null"); - - var allScripts = CommonPsScripts; + && string.IsNullOrEmpty(_psTestScript)) + throw new ArgumentNullException($"Both {nameof(_callingClassName)} and {nameof(_psTestScript)} are null"); - if(_newPsScriptFilename != null) + var allScripts = _psCommonScripts; + if (_psTestScript != null) { - allScripts.Add(_newPsScriptFilename); + allScripts.Add(_psTestScript); } - - var allScriptsWithPath = _projectSubfolderForTestsName == null - ? allScripts - : allScripts.Select(s => Path.Combine(_projectSubfolderForTestsName, s)); + var allScriptsWithPath = allScripts.Select(s => Path.Combine(_testBaseFolderName, s)); - var allModules = RmModules; + var allModules = _psAzModules; allModules.AddRange(allScriptsWithPath); return allModules.ToArray(); @@ -277,33 +305,24 @@ protected void SetupSessionAndProfile() protected void SetupAzureContext() { const string tenantIdKey = "TenantId"; - const string domainKey = "Domain"; const string subscriptionIdKey = "SubscriptionId"; const string undefined = "Undefined"; var zeroGuid = Guid.Empty.ToString(); const string dummyGuid = "395544B0-BF41-429D-921F-E1CA2252FCF4"; string tenantId = null; - string userDomain = null; string subscriptionId = null; switch (HttpMockServer.Mode) { case HttpRecorderMode.Record: var environment = TestEnvironmentFactory.GetTestEnvironment(); - tenantId = environment.Tenant; - userDomain = string.IsNullOrEmpty(environment.UserName) - ? string.Empty - : environment.UserName.Split(new[] { "@" }, StringSplitOptions.RemoveEmptyEntries).Last(); - + tenantId = environment.TenantId; subscriptionId = environment.SubscriptionId; break; case HttpRecorderMode.Playback: tenantId = HttpMockServer.Variables.ContainsKey(tenantIdKey) ? HttpMockServer.Variables[tenantIdKey] : dummyGuid; - userDomain = HttpMockServer.Variables.ContainsKey(domainKey) - ? HttpMockServer.Variables[domainKey] - : "testdomain.onmicrosoft.com"; subscriptionId = HttpMockServer.Variables.ContainsKey(subscriptionIdKey) ? HttpMockServer.Variables[subscriptionIdKey] : zeroGuid; @@ -318,43 +337,41 @@ protected void SetupAzureContext() AzureRmProfileProvider.Instance.Profile.DefaultContext.Subscription.Id = subscriptionId ?? undefined; } - protected void SetupMockServerMatcher() + protected void SetupMockServer() { - var resourceProviders = _matcherResourceProviders?.Count > 0 - ? _matcherResourceProviders - : new Dictionary // default - { - {"Microsoft.Resources", null}, - {"Microsoft.Features", null}, - {"Microsoft.Authorization", null}, - {"Providers.Test", null}, - }; - - var extraUserAgentsToIgnore = new Dictionary // default - { - {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"}, - }; - - _matcherExtraUserAgentsToIgnore?.Keys.ForEach(k => extraUserAgentsToIgnore.Add(k, _matcherExtraUserAgentsToIgnore[k])); //extra - - var userAgentsToIgnore = _matcherNewUserAgentsToIgnore?.Count > 0 - ? _matcherNewUserAgentsToIgnore - : extraUserAgentsToIgnore; + var resourceProvidersToIgnore = _matcherResourceProvidersToIgnore?.Count > 0 + ? _matcherResourceProvidersToIgnore + : new Dictionary + { + {"Microsoft.Resources", null}, + {"Microsoft.Features", null}, + {"Microsoft.Authorization", null}, + {"Providers.Test", null}, + }; + + var userAgentsToIgnore = _matcherUserAgentsToIgnore?.Count > 0 + ? _matcherUserAgentsToIgnore + : new Dictionary + { + {"Microsoft.Azure.Management.Resources.ResourceManagementClient", "2016-02-01"}, + }; - HttpMockServer.Matcher = RecordMatcher(true, resourceProviders, userAgentsToIgnore); + _recordMatcher ??= (ignoreResourcesClient, resourceProviders, userAgentsToIgnore) => new PermissiveRecordMatcherWithApiExclusion(ignoreResourcesClient, resourceProviders, userAgentsToIgnore); + HttpMockServer.Matcher = _recordMatcher(_matcherIgnoreResourceClient, resourceProvidersToIgnore, userAgentsToIgnore); + HttpMockServer.RecordsDirectory = Path.Combine(_testProjectPath, "SessionRecords"); } - protected void SetupManagementClients(MockContext context) + protected object[] SetupServiceClients(MockContext context) { - if (this._initializedManagementClients != null) { - var clients = new List(); - foreach (var client in this._initializedManagementClients) - { - clients.Add(client(context)); - } - Helper.SetupManagementClients(clients.ToArray()); + if (_initializedServiceClients == null) + return Array.Empty(); + + var clients = new List(); + foreach (var client in _initializedServiceClients) + { + clients.Add(client(context)); } + return clients.ToArray(); } - #endregion } } diff --git a/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs b/tools/TestFx/TestModelExtensions.cs similarity index 94% rename from tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs rename to tools/TestFx/TestModelExtensions.cs index bdf4e6e43d1b..80165761cd97 100644 --- a/tools/ScenarioTest.ResourceManager/Extensions/TestModelExtensions.cs +++ b/tools/TestFx/TestModelExtensions.cs @@ -1,5 +1,4 @@ -using Microsoft.Azure.Commands.Common.Authentication.Abstractions; -// ---------------------------------------------------------------------------------- +// ---------------------------------------------------------------------------------- // // Copyright Microsoft Corporation // Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,10 +12,11 @@ // limitations under the License. // ---------------------------------------------------------------------------------- +using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using System; using System.Collections.Generic; -namespace Microsoft.Azure.Commands.ScenarioTest.Extensions +namespace Microsoft.Azure.Commands.TestFx { public static class TestModelExtensions { @@ -28,8 +28,7 @@ public static class TestModelExtensions /// true if the models are equal, or false otherwise public static bool CheckExtensionsEqual(this IExtensibleModel model, IExtensibleModel other) { - return model != null && other != null - && CheckEquality(model.ExtendedProperties, other.ExtendedProperties); + return model != null && other != null && CheckEquality(model.ExtendedProperties, other.ExtendedProperties); } /// @@ -81,7 +80,7 @@ public static bool IsEqual(this IAzureSubscription baseSub, IAzureSubscription o /// Treu fi the elements of the environment are equal, otherwise false public static bool IsEqual(this IAzureEnvironment environment, IAzureEnvironment other) { - return (environment == null && other == null) + return (environment == null && other == null) || environment.CheckExtensionsEqual(other); } @@ -148,6 +147,5 @@ static bool CheckEquality(IDictionary current, IDictionary ParseConnectionString(string connectionString) + { + // Temporary connection string parser. We should replace with more robust one + IDictionary settings = new Dictionary(); + if (!string.IsNullOrEmpty(connectionString)) + { + string[] pairs = connectionString.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); + try + { + foreach (string pair in pairs) + { + string[] keyValue = pair.Split(new char[] { '=' }, 2); + string key = keyValue[0].Trim(); + string value = keyValue[1].Trim(); + settings[key] = value; + } + + } + catch (NullReferenceException ex) + { + throw new ArgumentException( + string.Format("Connection string \"{0}\" is invalid", connectionString), + "connectionString", ex); + } + } + return settings; + } + } +} diff --git a/tools/TestFx/TokenInfo.cs b/tools/TestFx/TokenInfo.cs new file mode 100644 index 000000000000..4d995c9de6c4 --- /dev/null +++ b/tools/TestFx/TokenInfo.cs @@ -0,0 +1,26 @@ +// ---------------------------------------------------------------------------------- +// +// Copyright Microsoft Corporation +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------------- + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Microsoft.Azure.Commands.TestFx +{ + public enum TokenAudience + { + Management, + Graph + } +} diff --git a/tools/ScenarioTest.ResourceManager/XunitTracingInterceptor.cs b/tools/TestFx/XunitTracingInterceptor.cs similarity index 92% rename from tools/ScenarioTest.ResourceManager/XunitTracingInterceptor.cs rename to tools/TestFx/XunitTracingInterceptor.cs index 1807eae137ac..779de54c06ca 100644 --- a/tools/ScenarioTest.ResourceManager/XunitTracingInterceptor.cs +++ b/tools/TestFx/XunitTracingInterceptor.cs @@ -16,21 +16,17 @@ using Microsoft.WindowsAzure.Commands.Utilities.Common; using System; using System.Collections.Generic; -using System.IO; using System.Net.Http; using System.Reflection; using Xunit.Abstractions; namespace Microsoft.Azure.ServiceManagement.Common.Models { - public class XunitTracingInterceptor : Hyak.Common.ICloudTracingInterceptor + public class XunitTracingInterceptor : ICloudTracingInterceptor { - private readonly string callingAssembly; - public XunitTracingInterceptor(ITestOutputHelper output) { traceOutput = output; - callingAssembly = Assembly.GetCallingAssembly().FullName.Split(new[] { ',' })[0]; } public ITestOutputHelper traceOutput;