public static void TransactionCleanupTest(string connectionString) { SqlConnection.ClearAllPools(); ConnectionPoolWrapper connectionPool = null; using (TransactionScope transScope = new()) { using SqlConnection connection1 = new(connectionString); using SqlConnection connection2 = new(connectionString); connection1.Open(); connection2.Open(); InternalConnectionWrapper internalConnection1 = new(connection1); connectionPool = new ConnectionPoolWrapper(connection1); connectionPool.Cleanup(); Assert.Equal(2, connectionPool.ConnectionCount); connection1.Close(); connection2.Close(); connectionPool.Cleanup(); Assert.Equal(2, connectionPool.ConnectionCount); connectionPool.Cleanup(); Assert.Equal(2, connectionPool.ConnectionCount); transScope.Complete(); } }
/// <summary> /// Tests that using the same connection string results in the same pool\internal connection and a different string results in a different pool\internal connection /// </summary> /// <param name="connectionString"></param> private static void BasicConnectionPoolingTest(string connectionString) { SqlConnection connection = new SqlConnection(connectionString); connection.Open(); InternalConnectionWrapper internalConnection = new InternalConnectionWrapper(connection); ConnectionPoolWrapper connectionPool = new ConnectionPoolWrapper(connection); connection.Close(); SqlConnection connection2 = new SqlConnection(connectionString); connection2.Open(); Assert.True(internalConnection.IsInternalConnectionOf(connection2), "New connection does not use same internal connection"); Assert.True(connectionPool.ContainsConnection(connection2), "New connection is in a different pool"); connection2.Close(); SqlConnection connection3 = new SqlConnection(connectionString + ";App=SqlConnectionPoolUnitTest;"); connection3.Open(); Assert.False(internalConnection.IsInternalConnectionOf(connection3), "Connection with different connection string uses same internal connection"); Assert.False(connectionPool.ContainsConnection(connection3), "Connection with different connection string uses same connection pool"); connection3.Close(); connectionPool.Cleanup(); SqlConnection connection4 = new SqlConnection(connectionString); connection4.Open(); Assert.True(internalConnection.IsInternalConnectionOf(connection4), "New connection does not use same internal connection"); Assert.True(connectionPool.ContainsConnection(connection4), "New connection is in a different pool"); connection4.Close(); }
/// <summary> /// Checks if an 'emancipated' internal connection is reclaimed when a new connection is opened AND we hit max pool size /// NOTE: 'emancipated' means that the internal connection's SqlConnection has fallen out of scope and has no references, but was not explicitly disposed\closed /// </summary> /// <param name="connectionString"></param> private static void ReclaimEmancipatedOnOpenTest(string connectionString) { string newConnectionString = (new SqlConnectionStringBuilder(connectionString) { MaxPoolSize = 1 }).ConnectionString; SqlConnection.ClearAllPools(); InternalConnectionWrapper internalConnection = CreateEmancipatedConnection(newConnectionString); ConnectionPoolWrapper connectionPool = internalConnection.ConnectionPool; GC.Collect(); GC.WaitForPendingFinalizers(); DataTestUtility.AssertEqualsWithDescription(1, connectionPool.ConnectionCount, "Wrong number of connections in the pool."); DataTestUtility.AssertEqualsWithDescription(0, connectionPool.FreeConnectionCount, "Wrong number of free connections in the pool."); using (SqlConnection connection = new SqlConnection(newConnectionString)) { connection.Open(); Assert.True(internalConnection.IsInternalConnectionOf(connection), "Connection has wrong internal connection"); Assert.True(connectionPool.ContainsConnection(connection), "Connection is in wrong connection pool"); } }
public static void MaxPoolWaitForConnectionTest(string connectionString) { string newConnectionString = (new SqlConnectionStringBuilder(connectionString) { MaxPoolSize = 1 }).ConnectionString; SqlConnection.ClearAllPools(); using SqlConnection connection1 = new SqlConnection(newConnectionString); connection1.Open(); InternalConnectionWrapper internalConnection = new InternalConnectionWrapper(connection1); ConnectionPoolWrapper connectionPool = new ConnectionPoolWrapper(connection1); ManualResetEventSlim taskAllowedToSpeak = new ManualResetEventSlim(false); Task waitTask = Task.Factory.StartNew(() => MaxPoolWaitForConnectionTask(newConnectionString, internalConnection, connectionPool, taskAllowedToSpeak)); int count = 5; while (waitTask.Status == TaskStatus.WaitingToRun && count-- > 0) { Thread.Sleep(200); } Assert.Equal(TaskStatus.Running, waitTask.Status); connection1.Close(); taskAllowedToSpeak.Set(); waitTask.Wait(); Assert.Equal(TaskStatus.RanToCompletion, waitTask.Status); }
public static void BasicTransactionPoolTest(string connectionString) { SqlConnection.ClearAllPools(); ConnectionPoolWrapper connectionPool = null; using (TransactionScope transScope = new()) { using SqlConnection connection1 = new(connectionString); using SqlConnection connection2 = new(connectionString); connection1.Open(); connection2.Open(); connectionPool = new ConnectionPoolWrapper(connection1); InternalConnectionWrapper internalConnection1 = new(connection1); InternalConnectionWrapper internalConnection2 = new(connection2); Assert.True(internalConnection1.IsEnlistedInTransaction, "First connection not in transaction"); Assert.True(internalConnection1.IsTransactionRoot, "First connection not transaction root"); Assert.True(internalConnection2.IsEnlistedInTransaction, "Second connection not in transaction"); Assert.False(internalConnection2.IsTransactionRoot, "Second connection is transaction root"); // Attempt to re-use root connection connection1.Close(); using SqlConnection connection3 = new(connectionString); connection3.Open(); Assert.True(connectionPool.ContainsConnection(connection3), "New connection in wrong pool"); Assert.True(internalConnection1.IsInternalConnectionOf(connection3), "Root connection was not re-used"); // Attempt to re-use non-root connection connection2.Close(); using SqlConnection connection4 = new(connectionString); connection4.Open(); Assert.True(internalConnection2.IsInternalConnectionOf(connection4), "Connection did not re-use expected internal connection"); Assert.True(connectionPool.ContainsConnection(connection4), "New connection is in the wrong pool"); connection4.Close(); // Use a different connection string using SqlConnection connection5 = new(connectionString + ";App=SqlConnectionPoolUnitTest;"); connection5.Open(); Assert.False(internalConnection2.IsInternalConnectionOf(connection5), "Connection with different connection string re-used internal connection"); Assert.False(connectionPool.ContainsConnection(connection5), "Connection with different connection string is in same pool"); connection5.Close(); transScope.Complete(); } Assert.Equal(2, connectionPool.ConnectionCount); }
/// <summary> /// Tests if clearing all of the pools does actually remove the pools /// </summary> /// <param name="connectionString"></param> private static void ClearAllPoolsTest(string connectionString) { SqlConnection.ClearAllPools(); Assert.True(0 == ConnectionPoolWrapper.AllConnectionPools().Length, "Pools exist after clearing all pools"); SqlConnection connection = new SqlConnection(connectionString); connection.Open(); ConnectionPoolWrapper pool = new ConnectionPoolWrapper(connection); connection.Close(); ConnectionPoolWrapper[] allPools = ConnectionPoolWrapper.AllConnectionPools(); DataTestUtility.AssertEqualsWithDescription(1, allPools.Length, "Incorrect number of pools exist."); Assert.True(allPools[0].Equals(pool), "Saved pool is not in the list of all pools"); DataTestUtility.AssertEqualsWithDescription(1, pool.ConnectionCount, "Saved pool has incorrect number of connections"); SqlConnection.ClearAllPools(); Assert.True(0 == ConnectionPoolWrapper.AllConnectionPools().Length, "Pools exist after clearing all pools"); DataTestUtility.AssertEqualsWithDescription(0, pool.ConnectionCount, "Saved pool has incorrect number of connections."); }
public static void AccessTokenConnectionPoolingTest() { // Remove cred info and add invalid token string[] credKeys = { "User ID", "Password", "UID", "PWD", "Authentication" }; string connectionString = DataTestUtility.RemoveKeysInConnStr(DataTestUtility.AADPasswordConnectionString, credKeys); SqlConnection connection = new SqlConnection(connectionString); connection.AccessToken = DataTestUtility.GetAccessToken(); connection.Open(); InternalConnectionWrapper internalConnection = new InternalConnectionWrapper(connection); ConnectionPoolWrapper connectionPool = new ConnectionPoolWrapper(connection); connection.Close(); SqlConnection connection2 = new SqlConnection(connectionString); connection2.AccessToken = DataTestUtility.GetAccessToken(); connection2.Open(); Assert.True(internalConnection.IsInternalConnectionOf(connection2), "New connection does not use same internal connection"); Assert.True(connectionPool.ContainsConnection(connection2), "New connection is in a different pool"); connection2.Close(); SqlConnection connection3 = new SqlConnection(connectionString + ";App=SqlConnectionPoolUnitTest;"); connection3.AccessToken = DataTestUtility.GetAccessToken(); connection3.Open(); Assert.False(internalConnection.IsInternalConnectionOf(connection3), "Connection with different connection string uses same internal connection"); Assert.False(connectionPool.ContainsConnection(connection3), "Connection with different connection string uses same connection pool"); connection3.Close(); connectionPool.Cleanup(); SqlConnection connection4 = new SqlConnection(connectionString); connection4.AccessToken = DataTestUtility.GetAccessToken(); connection4.Open(); Assert.True(internalConnection.IsInternalConnectionOf(connection4), "New connection does not use same internal connection"); Assert.True(connectionPool.ContainsConnection(connection4), "New connection is in a different pool"); connection4.Close(); }
private static void MaxPoolWaitForConnectionTask(string connectionString, InternalConnectionWrapper internalConnection, ConnectionPoolWrapper connectionPool, ManualResetEventSlim waitToSpeak) { using SqlConnection connection = new SqlConnection(connectionString); connection.Open(); waitToSpeak.Wait(); Assert.True(internalConnection.IsInternalConnectionOf(connection), "Connection has wrong internal connection"); Assert.True(connectionPool.ContainsConnection(connection), "Connection is in wrong connection pool"); }