Skip to content

Conversation

@mdaigle
Copy link
Contributor

@mdaigle mdaigle commented Nov 24, 2025

Description

The flow of transacting connections through the connection pool is tested by manual tests, but these lack coverage of more intricate scenarios:

  • reuse of transacting connections
  • concurrent access to the pool
  • concurrent connection requests for the same transaction
  • nested transactions
  • interplay with non-transacting connections
  • pool saturation (all slots used by transacting connections)
  • ordering of transaction completion and connection cleanup

This PR adds the missing test coverage. Also includes minor refactors to improve test visibility of properties and types.

Issues

#3356

Testing

Described above.

Copilot AI review requested due to automatic review settings November 24, 2025 19:53
Copilot finished reviewing on behalf of mdaigle November 24, 2025 19:57
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds comprehensive stress tests for connection pool transaction handling under high concurrency scenarios. The tests verify that the WaitHandleDbConnectionPool and TransactedConnectionPool correctly manage connections when multiple threads perform transactional operations concurrently. Additionally, the PR removes several transitive package references for vulnerable dependencies that are no longer needed.

Key Changes

  • Added WaitHandleDbConnectionPoolTransactionStressTest.cs with extensive transaction stress tests covering various concurrency patterns
  • Exposed internal properties in WaitHandleDbConnectionPool and TransactedConnectionPool for test observability
  • Removed explicit references to System.Formats.Asn1, System.Text.Json, and System.Text.Encodings.Web packages (transitive dependencies)

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
WaitHandleDbConnectionPoolTransactionStressTest.cs New comprehensive test file with 1125 lines covering transaction stress scenarios including per-iteration transactions, per-thread transactions, shared transactions, pool saturation, nested transactions, mixed transacted/non-transacted operations, and edge cases
WaitHandleDbConnectionPool.cs Changed MaxPoolSize and MinPoolSize from private to internal, and exposed TransactedConnectionPool property as internal for test observability
TransactedConnectionPool.cs Changed TransactedConnectionList to internal and replaced private _transactedCxns dictionary with internal TransactedConnections property for test access
Microsoft.Data.SqlClient.ExtUtilities.csproj Removed explicit reference to System.Formats.Asn1 package
netcore/src/Microsoft.Data.SqlClient.csproj Removed explicit reference to System.Text.Json package
netcore/ref/Microsoft.Data.SqlClient.csproj Removed explicit reference to System.Text.Json package
AzureKeyVaultProvider.csproj Removed explicit reference to System.Text.Encodings.Web package

@mdaigle mdaigle marked this pull request as ready for review November 24, 2025 22:33
@mdaigle mdaigle requested a review from a team as a code owner November 24, 2025 22:33
Copilot AI review requested due to automatic review settings November 24, 2025 22:33
@mdaigle mdaigle added this to the 7.0.0-preview3 milestone Nov 24, 2025
Copilot finished reviewing on behalf of mdaigle November 24, 2025 22:37
Copy link
Contributor

Copilot AI left a comment

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 8 out of 8 changed files in this pull request and generated 5 comments.

@paulmedynski paulmedynski self-assigned this Nov 27, 2025
Copy link
Contributor

@benrr101 benrr101 left a comment

Choose a reason for hiding this comment

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

The big problem here is adding stress tests to the unit test project. I can't approve that without some discussion on it.

<PackageReference Include="System.Security.Cryptography.Pkcs" />

<!-- Transitive dependencies that would otherwise bring in older, vulnerable versions. -->
<PackageReference Include="System.Text.Json" />
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't we want our ref packages to have the same references as the implementation packages?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll clean these up as part of DRI this sprint. Had to include them here to get some build errors addressed.

</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Core" />
<PackageReference Include="System.Text.Encodings.Web" />
Copy link
Contributor

Choose a reason for hiding this comment

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

How is this related to adding stress tests for the connection pool?

/// These tests verify that pool metrics remain consistent when connections are rapidly opened and closed
/// with intermingled transactions in a highly concurrent environment.
/// </summary>
public class WaitHandleDbConnectionPoolTransactionStressTest : IDisposable
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm really really really hesitant to approve putting stress tests into the unit test project. Our goal here should be to have unit tests be atomic tests of units of code that can be mocked and stubbed to coerce certain desired behaviors. Stress tests don't fit that bill, since they often are dependent on unexpected behaviors outside the scope of the code itself (system load, primarily).

We've sort of boxed ourselves into a corner here. The test TDS server is way too large to really be considered "unit testing". The code itself isn't structured for proper unit testing. And the stress test project isn't really ready for things to be moved into it.

I'd really like it if we address this from a different angle. Either move it into the stress test project (and I can help with that since I've still got the stress test project plans in my head a bit), or come up with a way to get the fake TDS server tests/code out of (or isolated within) the unit test project.

Copy link
Contributor Author

@mdaigle mdaigle Dec 1, 2025

Choose a reason for hiding this comment

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

I agree, but these tests don't use the test TDS server, they use mocked connections.

/// <value>The IDbConnectionPool instance that owns this transacted pool.</value>
internal IDbConnectionPool Pool { get; }

internal Dictionary<Transaction, TransactedConnectionList> TransactedConnections { get; private set; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Don't need private set here.

</ItemGroup>
<ItemGroup>
<PackageReference Include="Azure.Core" />
<PackageReference Include="System.Text.Encodings.Web" />
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the scoop with these package removals? Have the transitive problems been solved somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll clean these up. Visual studio was complaining, so I did this to appease it. I think it was just holding on to stale partial build state.

Task.WaitAll(tasks);

// Assert
AssertPoolMetrics(_pool);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should you be checking that the min/max are never exceeded at each iteration? This will just check that the pool currently hasn't exceeded those thresholds, not that it never did.

{
var owner = new SqlConnection();
_pool.TryGetConnection(owner, null, new DbConnectionOptions("", null), out var conn);
Assert.NotNull(conn);
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a way to confirm that this conn is enlisted with transaction?

{
tasks[t] = Task.Run(() =>
{
using (var innerScope = new TransactionScope(transaction))
Copy link
Contributor

Choose a reason for hiding this comment

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

What effect does innerScope have here? Should conn be associated to the inner scope, the outer scope, something else?

}

// Shutdown pool while operations are in progress
_pool.Shutdown();
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we certain there are operations in progress here? It's possible all tasks have run to completion already.

@benrr101 benrr101 added the Area\Tests Issues that are targeted to tests or test projects label Dec 2, 2025
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

None yet

Development

Successfully merging this pull request may close these issues.

4 participants