Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ci-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@
"Compute",
"Functions",
"KeyVault",
"KubernetersConfiguration",
"KubernetesConfiguration",
"Network",
"PostgreSql",
"Purview",
Expand Down
29 changes: 19 additions & 10 deletions tools/Modules/TestFx-Tasks.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ $script:TestFxEnvExtraPropKeys = @(
)

function Set-TestFxEnvironment {
[CmdletBinding(DefaultParameterSetName = "NewServicePrincipal")]
[CmdletBinding(DefaultParameterSetName = "UserAccount")]
param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
Expand All @@ -27,6 +27,10 @@ function Set-TestFxEnvironment {
[ValidateNotNullOrEmpty()]
[guid] $TenantId,

[Parameter(Mandatory, ParameterSetName = "UserAccount")]
[ValidateNotNullOrEmpty()]
[guid] $UserId,

[Parameter(Mandatory, ParameterSetName = "NewServicePrincipal")]
[ValidateNotNullOrEmpty()]
[string] $ServicePrincipalDisplayName,
Expand Down Expand Up @@ -108,11 +112,23 @@ function Set-TestFxEnvironment {
}
}

$testFxEnvProps = [PSCustomObject]@{
Environment = $TargetEnvironment
SubscriptionId = $SubscriptionId
TenantId = $TenantId
HttpRecorderMode = $RecorderMode
}

switch ($PSCmdlet.ParameterSetName) {
"UserAccount" {
$testFxEnvProps | Add-Member -NotePropertyName UserId -NotePropertyValue $UserId
}
"NewServicePrincipal" {
$sp = New-TestFxServicePrincipal -SubscriptionId $SubscriptionId -ServicePrincipalDisplayName $ServicePrincipalDisplayName -Force:$Force
$spAppId = $sp.AppId
$spSecret = $sp.PasswordCredentials.SecretText
$testFxEnvProps | Add-Member -NotePropertyName ServicePrincipal -NotePropertyValue $spAppId
$testFxEnvProps | Add-Member -NotePropertyName ServicePrincipalSecret -NotePropertyValue $spSecret
}
"ExistingServicePrincipal" {
$sp = Get-AzADServicePrincipal -ApplicationId $ServicePrincipalId
Expand All @@ -122,18 +138,11 @@ function Set-TestFxEnvironment {

$spAppId = $ServicePrincipalId
$spSecret = $ServicePrincipalSecret
$testFxEnvProps | Add-Member -NotePropertyName ServicePrincipal -NotePropertyValue $spAppId
$testFxEnvProps | Add-Member -NotePropertyName ServicePrincipalSecret -NotePropertyValue $spSecret
}
}

$testFxEnvProps = [PSCustomObject]@{
Environment = $TargetEnvironment
SubscriptionId = $SubscriptionId
TenantId = $TenantId
ServicePrincipal = $spAppId
ServicePrincipalSecret = $spSecret
HttpRecorderMode = $RecorderMode
}

$script:testFxEnvExtraPropKeys | ForEach-Object {
if ($PSBoundParameters.ContainsKey($_)) {
$testFxEnvProps | Add-Member -NotePropertyName $_ -NotePropertyValue $PSBoundParameters[$_]
Expand Down
40 changes: 1 addition & 39 deletions tools/TestFx/ConnectionString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public class ConnectionString
private Dictionary<string, string> _keyValuePairs;
private string _connString;
private StringBuilder _parseErrorSb;
private string DEFAULT_TENANTID = "72f988bf-86f1-41af-91ab-2d7cd011db47";

public Dictionary<string, string> KeyValuePairs
{
Expand Down Expand Up @@ -75,46 +74,13 @@ 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 = @"(?<KeyName>[^=]+)=(?<KeyValue>.+)";

if (_parseErrorSb != null) _parseErrorSb.Clear();
_parseErrorSb?.Clear();

if (string.IsNullOrEmpty(connString))
{
Expand Down Expand Up @@ -161,10 +127,6 @@ public void Parse(string connString)
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();
}
}

Expand Down
2 changes: 1 addition & 1 deletion tools/TestFx/DelegatingHandlers/HttpMockServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class HttpMockServer : DelegatingHandler

public static string CallerIdentity { get; set; }
public static string TestIdentity { get; set; }
public static HttpRecorderMode Mode { get; set; }
public static HttpRecorderMode Mode { get; internal set; }
public static IRecordMatcher Matcher { get; set; }
public static string RecordsDirectory { get; set; }
public static Dictionary<string, string> Variables { get; private set; }
Expand Down
114 changes: 58 additions & 56 deletions tools/TestFx/EnvironmentSetupHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Management.Automation;
Expand All @@ -40,9 +39,9 @@ namespace Microsoft.Azure.Commands.TestFx
{
public class EnvironmentSetupHelper
{
private const string TestEnvironmentName = "__test-environment";
private const string TestFxEnvironmentName = "__testfx-environment";

private const string TestSubscriptionName = "__test-subscriptions";
private const string TestFxSubscriptionName = "__testfx-subscription";

private static string PackageDirectoryFromCommon { get; } = GetConfigDirectory();

Expand Down Expand Up @@ -134,9 +133,6 @@ public EnvironmentSetupHelper()
// Ignore SSL errors
System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) => true;

// Set RunningMocked
TestMockSupport.RunningMocked = HttpMockServer.GetCurrentMode() == HttpRecorderMode.Playback;

if (File.Exists(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), Resources.AzureDirectoryName, "testcredentials.json")))
{
SetEnvironmentVariableFromCredentialFile();
Expand Down Expand Up @@ -388,62 +384,67 @@ public void SetupAzureEnvironmentFromEnvironmentVariables(AzureModule mode)
throw new NotSupportedException("RDFE environment is not supported in .Net Core");
}

if (currentEnvironment.UserName == null)
{
currentEnvironment.UserName = "[email protected]";
}

SetAuthenticationFactory(currentEnvironment);
AzureEnvironment environment = new AzureEnvironment { Name = TestEnvironmentName };
Debug.Assert(currentEnvironment != null);
environment.ActiveDirectoryAuthority = currentEnvironment.Endpoints.AADAuthUri.AbsoluteUri;
environment.GalleryUrl = currentEnvironment.Endpoints.GalleryUri?.AbsoluteUri;
environment.ServiceManagementUrl = currentEnvironment.BaseUri.AbsoluteUri;
environment.ResourceManagerUrl = currentEnvironment.Endpoints.ResourceManagementUri.AbsoluteUri;
environment.GraphUrl = currentEnvironment.Endpoints.GraphUri.AbsoluteUri;
environment.AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix = currentEnvironment.Endpoints.DataLakeAnalyticsJobAndCatalogServiceUri.OriginalString.Replace("https://", ""); // because it is just a sufix
environment.AzureDataLakeStoreFileSystemEndpointSuffix = currentEnvironment.Endpoints.DataLakeStoreServiceUri.OriginalString.Replace("https://", ""); // because it is just a sufix
environment.StorageEndpointSuffix = AzureEnvironmentConstants.AzureStorageEndpointSuffix;
environment.AzureKeyVaultDnsSuffix = AzureEnvironmentConstants.AzureKeyVaultDnsSuffix;
environment.AzureKeyVaultServiceEndpointResourceId = AzureEnvironmentConstants.AzureKeyVaultServiceEndpointResourceId;
environment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.MicrosoftGraphUrl, currentEnvironment.Endpoints.GraphUri.AbsoluteUri);
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<AzureRmProfile>().EnvironmentTable.ContainsKey(TestEnvironmentName))
{
AzureRmProfileProvider.Instance.GetProfile<AzureRmProfile>().EnvironmentTable[TestEnvironmentName] = environment;
}

if (currentEnvironment.SubscriptionId != null)
{
var testSubscription = new AzureSubscription
{
Id = currentEnvironment.SubscriptionId,
Name = TestSubscriptionName,
};

testSubscription.SetEnvironment(TestEnvironmentName);
testSubscription.SetAccount(currentEnvironment.UserName);
AzureEnvironment testEnvironment = new AzureEnvironment
{
Name = TestFxEnvironmentName,
ActiveDirectoryAuthority = currentEnvironment.Endpoints.AADAuthUri.AbsoluteUri,
ActiveDirectoryServiceEndpointResourceId = currentEnvironment.Endpoints.AADTokenAudienceUri.AbsoluteUri,
GraphUrl = currentEnvironment.Endpoints.GraphUri.AbsoluteUri,
GraphEndpointResourceId = currentEnvironment.Endpoints.GraphTokenAudienceUri.AbsoluteUri,
ResourceManagerUrl = currentEnvironment.Endpoints.ResourceManagementUri.AbsoluteUri,
ServiceManagementUrl = currentEnvironment.Endpoints.ServiceManagementUri.AbsoluteUri,
GalleryUrl = currentEnvironment.Endpoints.GalleryUri?.AbsoluteUri,
AzureDataLakeAnalyticsCatalogAndJobEndpointSuffix = currentEnvironment.Endpoints.DataLakeAnalyticsJobAndCatalogServiceUri.OriginalString.Replace("https://", ""), // because it is just a sufix
AzureDataLakeStoreFileSystemEndpointSuffix = currentEnvironment.Endpoints.DataLakeStoreServiceUri.OriginalString.Replace("https://", ""), // because it is just a sufix
StorageEndpointSuffix = AzureEnvironmentConstants.AzureStorageEndpointSuffix,
AzureKeyVaultDnsSuffix = AzureEnvironmentConstants.AzureKeyVaultDnsSuffix,
AzureKeyVaultServiceEndpointResourceId = AzureEnvironmentConstants.AzureKeyVaultServiceEndpointResourceId
};
testEnvironment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.MicrosoftGraphUrl, currentEnvironment.Endpoints.GraphUri.AbsoluteUri);
testEnvironment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.OperationalInsightsEndpoint, "https://api.loganalytics.io/v1");
testEnvironment.ExtendedProperties.SetProperty(AzureEnvironment.ExtendedEndpoint.OperationalInsightsEndpointResourceId, "https://api.loganalytics.io");
if (!AzureRmProfileProvider.Instance.GetProfile<AzureRmProfile>().EnvironmentTable.ContainsKey(TestFxEnvironmentName))
{
AzureRmProfileProvider.Instance.GetProfile<AzureRmProfile>().EnvironmentTable[TestFxEnvironmentName] = testEnvironment;
}

AzureSubscription testSubscription = new AzureSubscription();
if (!string.IsNullOrEmpty(currentEnvironment.SubscriptionId))
{
testSubscription.Id = currentEnvironment.SubscriptionId;
testSubscription.Name = TestFxSubscriptionName;
testSubscription.SetEnvironment(TestFxEnvironmentName);
testSubscription.SetTenant(currentEnvironment.TenantId);
testSubscription.SetAccount(currentEnvironment.UserId);
testSubscription.SetDefault();
testSubscription.SetStorageAccount(Environment.GetEnvironmentVariable("AZURE_STORAGE_ACCOUNT"));
}

var testAccount = new AzureAccount()
{
Id = currentEnvironment.UserName,
Type = AzureAccount.AccountType.User,
};
AzureTenant testTenant = new AzureTenant();
if (!string.IsNullOrEmpty(currentEnvironment.TenantId))
{
testTenant.Id = currentEnvironment.TenantId;
}

testAccount.SetSubscriptions(currentEnvironment.SubscriptionId);
var testTenant = new AzureTenant() { Id = Guid.NewGuid().ToString() };
if (!string.IsNullOrEmpty(currentEnvironment.TenantId))
{
if (Guid.TryParse(currentEnvironment.TenantId, out _))
{
testTenant.Id = currentEnvironment.TenantId;
}
}
AzureRmProfileProvider.Instance.Profile.DefaultContext = new AzureContext(testSubscription, testAccount, environment, testTenant);
AzureAccount testAccount = new AzureAccount();
if (!string.IsNullOrEmpty(currentEnvironment.UserId))
{
testAccount.Id = currentEnvironment.UserId;
testAccount.Type = AzureAccount.AccountType.User;
}
else if (!string.IsNullOrEmpty(currentEnvironment.ServicePrincipalClientId) && !string.IsNullOrEmpty(currentEnvironment.ServicePrincipalSecret))
{
testAccount.Id = currentEnvironment.ServicePrincipalClientId;
testAccount.Type = AzureAccount.AccountType.ServicePrincipal;
}

testAccount.SetAccessToken(string.Empty);
testAccount.SetSubscriptions(currentEnvironment.SubscriptionId);
testAccount.SetTenants(currentEnvironment.TenantId);

AzureRmProfileProvider.Instance.Profile.DefaultContext = new AzureContext(testSubscription, testAccount, testEnvironment, testTenant);
}

private void SetAuthenticationFactory(TestEnvironment environment)
Expand All @@ -457,7 +458,7 @@ private void SetAuthenticationFactory(TestEnvironment environment)
.GetAwaiter()
.GetResult();

AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(environment.UserName, httpMessage.Headers.Authorization.Parameter);
AzureSession.Instance.AuthenticationFactory = new MockTokenAuthenticationFactory(environment.UserId, httpMessage.Headers.Authorization.Parameter);
}
}

Expand Down Expand Up @@ -524,6 +525,7 @@ public virtual Collection<PSObject> RunPowerShellTest(params string[] scripts)
Collection<PSObject> output = null;
foreach (var script in scripts)
{
Console.WriteLine($"Executing test: {script}");
TracingInterceptor?.Information(script);
powershell.AddScript(script);
}
Expand Down
4 changes: 1 addition & 3 deletions tools/TestFx/Mocks/MockClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
using Microsoft.Azure.Commands.Common.Authentication.Factories;
using Microsoft.Azure.Commands.Common.Authentication.Models;
using Microsoft.Rest.Azure;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using System;
using System.Collections.Generic;
using System.Diagnostics;
Expand All @@ -28,7 +27,6 @@
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;
using Microsoft.Azure.Commands.Common.MSGraph.Version1_0;
Expand Down Expand Up @@ -104,7 +102,7 @@ public TClient CreateCustomArmClient<TClient>(params object[] parameters) where
client = realClientFactory.CreateCustomArmClient<TClient>(newParameters);
}

if (TestMockSupport.RunningMocked && HttpMockServer.GetCurrentMode() != HttpRecorderMode.Record)
if (HttpMockServer.Mode == HttpRecorderMode.Playback)
{
if (client is IAzureClient azureClient)
{
Expand Down
3 changes: 3 additions & 0 deletions tools/TestFx/Mocks/MockContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.Azure.Commands.TestFx.DelegatingHandlers;
using Microsoft.Azure.Commands.TestFx.Recorder;
using Microsoft.Azure.Test.HttpRecorder;
using Microsoft.WindowsAzure.Commands.Utilities.Common;
using System;
using System.Collections.Generic;
using System.Net.Http;
Expand Down Expand Up @@ -66,6 +67,8 @@ public static MockContext Start(
}
HttpMockServer.Initialize(className, methodName);

TestMockSupport.RunningMocked = HttpMockServer.Mode == HttpRecorderMode.Playback;

return context;
}

Expand Down
Loading