Skip to content

Tests | Cleanup AAD Password auth from tests + code cleanup#4390

Open
cheenamalhotra wants to merge 11 commits into
mainfrom
dev/cheena/aad-test-improvements
Open

Tests | Cleanup AAD Password auth from tests + code cleanup#4390
cheenamalhotra wants to merge 11 commits into
mainfrom
dev/cheena/aad-test-improvements

Conversation

@cheenamalhotra

@cheenamalhotra cheenamalhotra commented Jun 23, 2026

Copy link
Copy Markdown
Member

Follow up changes to test suite after #4288 where AAD Password auth was disabled from pipelines. This PR removes the AAD Password Conn String parameter completely to make it easier for AAD tests to be managed.

What Changed

Pipeline / config

  • Replace AAD_PASSWORD_CONN_STR(_eastus) with AZURE_SQL_CONN_STRING_WestUS2 / AZURE_SQL_CONN_STRING_EastUS (bare conn string, no credentials).
  • Remove AADAuthorityURL config property, as its now unused.
  • Rename config property AADPasswordConnectionStringAzureSqlConnectionString across Config.cs, config.default.jsonc, and pipeline templates (update-config-file-step.yml, ci-run-tests-job.yml, dotnet-sqlclient-ci-core.yml, test-azure-package-ci-job.yml).
  • Move AADServicePrincipalId inside the IsFork == 'False' guard (matches existing policy for AADServicePrincipalSecret).

New shared test helpers (tests/Common/)

  • CommonUtils.cs: EnsureSeparator, GenerateRandomSecureString, GenerateRandomCharacters, GenerateObjectName.
  • StringExtensions.cs: fluent Add*AuthenticationToConnString extensions (Integrated, Interactive, DeviceCodeFlow, ServicePrincipal, WorkloadIdentity, MSI, Default) plus AddUserToConnString / AddPasswordToConnString. Tests now compose auth onto AzureSqlConnectionString dynamically — required for broker-aware test legs.

Test updates

  • ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs: removed all ActiveDirectoryPassword cases; rewrote MSI / Workload Identity / Device Code / Default / token-callback tests against the new helpers; applied target-typed new(), collection expressions, using SecureString, Assert.Equal(ConnectionState.Open, …).
  • DataTestUtility.cs, AADFedAuthTokenRefreshTest, ConnectionPoolTest, and Microsoft.Data.SqlClient.Extensions/Azure/test/AADConnectionTest.cs + Config.cs updated to match.
  • TESTGUIDE.md and .github/instructions/testing.instructions.md updated.

Breaking change (CI only)

Downstream pipelines / config.user.jsonc must rename AADPasswordConnectionStringAzureSqlConnectionString and supply a bare Azure SQL connection string (no Authentication=, User ID=, Password=). The variables AAD_PASSWORD_CONN_STR / _eastus are no longer consumed and can be retired.

Validation

  • dotnet build ManualTests / net9.0 — 0 warnings, 0 errors.
  • dotnet test UnitTests / net9.0 — 792 pass; 4 failures are pre-existing macOS-env issues (Windows-only SSPI + keychain-restricted AE fixtures), not regressions.
  • Full PR pipeline (validates renamed Azure-SQL secrets).
  • Tests updated.
  • No public API changes (test-only).

Future TODOs

  • Propogate changes to all release branches.
  • Remove AAD_PASSWORD_CONN_STR, AAD_PASSWORD_CONN_STR_eastus, AADAuthorityURL and Azure_Password variables from library.

Copilot AI review requested due to automatic review settings June 23, 2026 01:52
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board Jun 23, 2026
@cheenamalhotra cheenamalhotra added the Area\Tests Issues that are targeted to tests or test projects label Jun 23, 2026
@cheenamalhotra cheenamalhotra added this to the 7.1.0-preview2 milestone Jun 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes the Entra ID “password auth” connection-string configuration from the test suite (and CI templates) following the pipeline change in #4288, replacing it with a single “bare” AzureSqlConnectionString that tests extend at runtime to exercise specific authentication modes.

Changes:

  • Renamed AADPasswordConnectionStringAzureSqlConnectionString across test config (Config.cs/config.default.jsonc), docs, and Azure DevOps pipeline templates; updated pipeline variables accordingly.
  • Added shared test helpers under tests/Common/ (CommonUtils, StringExtensions) to compose auth/credential keywords onto a base connection string.
  • Updated ManualTests + Azure extensions tests to remove ActiveDirectoryPassword coverage and to use managed identity / token-based flows with the new helpers.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
TESTGUIDE.md Updates documented test config property name/meaning for AAD/Azure SQL tests.
src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Microsoft.Data.SqlClient.TestUtilities.csproj References the new shared test helper project.
src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/config.default.jsonc Renames config field and clarifies Azure SQL base conn string expectation (no creds).
src/Microsoft.Data.SqlClient/tests/tools/Microsoft.Data.SqlClient.TestUtilities/Config.cs Renames the config field to AzureSqlConnectionString.
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs Removes AAD password tests and rewrites AAD scenarios to use helpers and AzureSqlConnectionString.
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectionPoolTest/ConnectionPoolTest.cs Updates pooled AAD/token tests to use AzureSqlConnectionString and async token retrieval.
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/AADFedAuthTokenRefreshTest/AADFedAuthTokenRefreshTest.cs Switches the fed-auth refresh scenario to managed identity-based auth/provider usage.
src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/ManagedIdentityProvider.cs Renames the custom provider class to clarify it targets user-assigned MI.
src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs Renames config fields, adds MI-based token retrieval APIs, and removes AAD password token generation.
src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs Adds fluent helpers for composing auth/credential keywords and for removing auth/credential keywords.
src/Microsoft.Data.SqlClient/tests/Common/CommonUtils.cs Adds shared random/name helpers used by updated tests.
src/Microsoft.Data.SqlClient.Extensions/Azure/test/Config.cs Renames the Azure test config field read from config.jsonc.
src/Microsoft.Data.SqlClient.Extensions/Azure/test/AADConnectionTest.cs Updates Azure extension tests to build auth modes from the base Azure SQL conn string.
eng/pipelines/jobs/test-azure-package-ci-job.yml Switches pipeline config-writing to AzureSqlConnectionString and updates secret scoping.
eng/pipelines/dotnet-sqlclient-ci-core.yml Switches CI template config-writing to AzureSqlConnectionString (WestUS2/EastUS).
eng/pipelines/common/templates/steps/update-config-file-step.yml Renames template parameter and output property to AzureSqlConnectionString.
eng/pipelines/common/templates/jobs/ci-run-tests-job.yml Renames config pass-through property to AzureSqlConnectionString.
.github/instructions/testing.instructions.md Updates the test-config docs to match the renamed Azure SQL config property.

Comment thread src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs
Comment thread src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs
Comment thread src/Microsoft.Data.SqlClient.Extensions/Azure/test/Config.cs Outdated
Copilot AI review requested due to automatic review settings June 23, 2026 06:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 6 comments.

Comment thread src/Microsoft.Data.SqlClient/tests/Common/CommonUtils.cs Outdated
Comment thread src/Microsoft.Data.SqlClient/tests/Common/CommonUtils.cs
Comment thread src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs Outdated
Comment thread src/Microsoft.Data.SqlClient.Extensions/Azure/test/Config.cs
Copilot AI review requested due to automatic review settings June 23, 2026 08:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 29 changed files in this pull request and generated 5 comments.

Files not reviewed (1)
  • src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file

Comment thread src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs
Comment thread src/Microsoft.Data.SqlClient/tests/Common/CommonUtils.cs Outdated
Comment thread src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs
Copilot AI review requested due to automatic review settings June 24, 2026 02:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 29 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file

Comment thread src/Microsoft.Data.SqlClient/tests/Common/CommonUtils.cs Outdated
Comment thread src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs
Copilot AI review requested due to automatic review settings June 24, 2026 20:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 29 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file

@cheenamalhotra cheenamalhotra marked this pull request as ready for review June 25, 2026 00:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 29 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • src/Microsoft.Data.SqlClient/src/Resources/Strings.Designer.cs: Generated file

Comment thread src/Microsoft.Data.SqlClient/tests/Common/StringExtensions.cs
Comment thread TESTGUIDE.md
@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.85%. Comparing base (44e1b72) to head (853ffb6).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4390      +/-   ##
==========================================
- Coverage   65.32%   63.85%   -1.48%     
==========================================
  Files         285      281       -4     
  Lines       43373    66638   +23265     
==========================================
+ Hits        28335    42550   +14215     
- Misses      15038    24088    +9050     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 63.85% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@benrr101 benrr101 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the scope of these changes are a bit too broad. Don't mind cleanup where sensible, but I'm concerned about the intentions behind the connection string changes being more sweeping than we really want right now.


namespace Microsoft.Data.SqlClient.Tests.Common;

public static class CommonUtils

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bucket of "common utils" in the "common" project seems a bit too general purpose. It would be nice to maybe split them into more purposeful classes of utilities. Like ConnectionStringUtilities, RandomUtilities.

return string.Concat(prefix, path.Substring(0, Math.Min(length, path.Length)));
}

public static string GenerateObjectName()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a thing for this already, please use Paul/EdwardNeal's DatabaseObject.GetLongName/GetShortName

/// <summary>
/// Adds a user provided or a dummy user to the connection string to test the connection string parsing logic
/// </summary>
public static string AddUserToConnString(this string connectionString, string? user = null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we doing this with raw string manipulation rather than using ConnectionStringBuilder to manipulate it?

/// Extension methods for string class to add connection string keywords to connection string
/// for testing connection string parsing logic
/// </summary>
public static class StringExtensions

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, these are all connection string utilities. Unless there's a really good reason not to, we should be using ConnectionStringBuilder to manipulate connection strings.

Additionally, the EnsureSeparator method should be moved to here since these are all ConnectionStringUtilities.

/// <summary>
/// Adds user provided or a dummy password to the connection string to test the connection string parsing logic
/// </summary>
public static string AddPasswordToConnString(this string connectionString, string? password = null)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought the goal was to remove password auth from these tests 🤔

{
return AKVBaseUri != null && !string.IsNullOrEmpty(UserManagedIdentityClientId) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse();
}
public static bool IsAKVSetupAvailable() => AKVBaseUri != null && !string.IsNullOrEmpty(UserManagedIdentityClientId) && !string.IsNullOrEmpty(AKVTenantId) && IsNotAzureSynapse();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put these conditions on separate lines for readability?

return s_defaultCredential;
}
public static string GetUserIdentityConnectionString()
=> AzureSqlConnectionString

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be indented one more over

| `AADPasswordConnectionString` | Entra ID password auth |
| `TCPConnectionString` | Primary TCP connection to on-premises SQL Server |
| `NPConnectionString` | Named Pipes connection to on-premises SQL Server |
| `AzureSqlConnectionString` | Entra ID connection string to Azure SQL Database |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned with making this change.

The PR pipeline uses two different test runs, one for localhost, one for azure. The differentiation is made by running it once with an azure connection string for TCPConnectionString/NPConnectionString and then using a localhost connection string. This allows us to run the same set of tests on both environments, since the tests just specify if it can't run on Azure (or I suppose only run on Azure) based on the TCP/NP connection string that was provided.

Changing this "AADPasswordConnectionString" to "AzureSqlConnectionString" and changing the comments for TCP and NP mixes up the ideas. The new guidance suggests that tests are either azure-specific or localhost-specific. But, aside from the handful being changed in this PR, they are not azure/localhost specific. And, worse, in order to enable azure/localhost specific tests, we would need to duplicate all the existing tests that use TCP/NP.

eg, we'd have to change from

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnectionStringsSetUp))]
public void MyTest() { /* ... test that uses TCPConnectionString ... */ }

to

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsLocalhostConnectionStringsSetUp)]
public void MyTest_Localhost() { /* ... test that uses TCPConnectionString ... */ }

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsAzureConnectionStringsSetUp)]
public void MyTest_Azure() { /* ... test that uses AzureConnectionString ... */ }

That seems like a really bad idea to me.

I've been percolating on a better way for us to handle multiple connection strings for our test scenarios. I'd really like a bit of runway to put together a prototype for how it could be used to improve our manual tests.

But anyhow, my general feedback for this would be ... maybe we shouldn't change the name and guidance on these connection strings right now. Maybe we should just make sure that we eliminate the AAD password auth from the tests, but not go further than that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 can we just remove the 'AADPasswordConnectionString'? why do we need a replacement?

public void SqlVariantTest()
{
string tableName = DataTestUtility.GenerateObjectName();
string tableName = CommonUtils.GenerateObjectName();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be using DataTestUtility.GetShortName/GetLongName

@github-project-automation github-project-automation Bot moved this from In review to Waiting for customer in SqlClient Board Jun 25, 2026

@mdaigle mdaigle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have similar feedback to @benrr101. Looking for a few things:

  • using TCP connection string instead of a new azure connection string
  • using existing random generation helpers
  • using connection string builder in place of direct string manipulation

The second two could be left as backlog items because you're just shuffling existing code around.

| `AADPasswordConnectionString` | Entra ID password auth |
| `TCPConnectionString` | Primary TCP connection to on-premises SQL Server |
| `NPConnectionString` | Named Pipes connection to on-premises SQL Server |
| `AzureSqlConnectionString` | Entra ID connection string to Azure SQL Database |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 can we just remove the 'AADPasswordConnectionString'? why do we need a replacement?

string connStr = RemoveKeysInConnStr(Config.PasswordConnectionString, removeKeys) +
$"Authentication=Active Directory Service Principal; User ID={Config.ServicePrincipalId}; PWD={Config.ServicePrincipalSecret};";
ConnectAndDisconnect(connStr);
string connString = Config.AzureSqlConnString

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just modify the TCP connection string as needed in each test.


[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsAADPasswordConnStrSetup), nameof(DataTestUtility.IsAADAuthorityURLSetup))]
public static void AccessTokenConnectionPoolingTest()
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsAzureConnStringSetup))]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be able to use IsAzure and then look at the TCP connection string.

/// <param name="connStr">The connection string to modify.</param>
/// <param name="keysToRemove">The keys to remove from the connection string.</param>
/// <returns>The modified connection string with the specified keys removed.</returns>
public static string RemoveKeysInConnStr(this string connStr, string[] keysToRemove)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SqlConnectionStringBuilder provides this functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area\Tests Issues that are targeted to tests or test projects

Projects

Status: Waiting for customer

Development

Successfully merging this pull request may close these issues.

5 participants