Skip to content

Commit 93b6c9d

Browse files
committed
Add metric test case.
1 parent 1f776d8 commit 93b6c9d

File tree

1 file changed

+67
-0
lines changed
  • src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests

1 file changed

+67
-0
lines changed

src/Microsoft.Data.SqlClient/tests/ManualTests/TracingTests/MetricsTest.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,73 @@ public void StasisCounters_Functional()
177177
Assert.Equal(0, SqlClientEventSourceProps.StasisConnections);
178178
}
179179

180+
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureSynapse))]
181+
public void TransactedConnectionPool_VerifyActiveConnectionCounters()
182+
{
183+
// This test verifies that the active connection count metric never goes negative
184+
// when connections are returned to the pool while enlisted in a transaction.
185+
// This is a regression test for issue #3640 where an extra DeactivateConnection
186+
// call was causing the active connection count to go negative.
187+
188+
// Arrange
189+
var stringBuilder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString)
190+
{
191+
Pooling = true,
192+
Enlist = false,
193+
MinPoolSize = 0,
194+
MaxPoolSize = 10
195+
};
196+
197+
// Clear pools to start fresh
198+
ClearConnectionPools();
199+
200+
long initialActiveSoftConnections = SqlClientEventSourceProps.ActiveSoftConnections;
201+
long initialActiveHardConnections = SqlClientEventSourceProps.ActiveHardConnections;
202+
long initialActiveConnections = SqlClientEventSourceProps.ActiveConnections;
203+
204+
// Act and Assert
205+
// Verify counters at each step in the lifecycle of a transacted connection
206+
using (var txScope = new TransactionScope())
207+
{
208+
using (var conn = new SqlConnection(stringBuilder.ToString()))
209+
{
210+
conn.Open();
211+
conn.EnlistTransaction(System.Transactions.Transaction.Current);
212+
213+
if (SupportsActiveConnectionCounters)
214+
{
215+
// Connection should be active
216+
Assert.Equal(initialActiveSoftConnections + 1, SqlClientEventSourceProps.ActiveSoftConnections);
217+
Assert.Equal(initialActiveHardConnections + 1, SqlClientEventSourceProps.ActiveHardConnections);
218+
Assert.Equal(initialActiveConnections + 1, SqlClientEventSourceProps.ActiveConnections);
219+
}
220+
221+
conn.Close();
222+
223+
// Connection is returned to pool but still in transaction (stasis)
224+
if (SupportsActiveConnectionCounters)
225+
{
226+
// Connection should be deactivated (returned to pool)
227+
Assert.Equal(initialActiveSoftConnections, SqlClientEventSourceProps.ActiveSoftConnections);
228+
Assert.Equal(initialActiveHardConnections + 1, SqlClientEventSourceProps.ActiveHardConnections);
229+
Assert.Equal(initialActiveConnections, SqlClientEventSourceProps.ActiveConnections);
230+
}
231+
}
232+
233+
// Completing the transaction after the connection is closed ensures that the connection
234+
// is in the transacted pool at the time the transaction ends. This verifies that the
235+
// transition from the transacted pool back to the main pool properly updates the counters.
236+
txScope.Complete();
237+
}
238+
239+
if (SupportsActiveConnectionCounters)
240+
{
241+
Assert.Equal(initialActiveSoftConnections, SqlClientEventSourceProps.ActiveSoftConnections);
242+
Assert.Equal(initialActiveHardConnections+1, SqlClientEventSourceProps.ActiveHardConnections);
243+
Assert.Equal(initialActiveConnections, SqlClientEventSourceProps.ActiveConnections);
244+
}
245+
}
246+
180247
[ActiveIssue("https://github.com/dotnet/SqlClient/issues/3031")]
181248
[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup))]
182249
public void ReclaimedConnectionsCounter_Functional()

0 commit comments

Comments
 (0)