diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs index f7e79da653..089eb956e5 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -1856,7 +1856,7 @@ private bool TryOpen(TaskCompletionSource retry, SqlConnec } } - _applyTransientFaultHandling = (!overrides.HasFlag(SqlConnectionOverrides.OpenWithoutRetry) && retry == null && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); + _applyTransientFaultHandling = (!overrides.HasFlag(SqlConnectionOverrides.OpenWithoutRetry) && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); if (connectionOptions != null && (connectionOptions.Authentication == SqlAuthenticationMethod.SqlPassword || @@ -1885,7 +1885,7 @@ private bool TryOpen(TaskCompletionSource retry, SqlConnec // does not require GC.KeepAlive(this) because of ReRegisterForFinalize below. // Set future transient fault handling based on connection options - _applyTransientFaultHandling = (retry == null && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); + _applyTransientFaultHandling = connectionOptions != null && connectionOptions.ConnectRetryCount > 0; var tdsInnerConnection = (SqlInternalConnectionTds)InnerConnection; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs index 681faaaf15..83233d4ac3 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnection.cs @@ -2068,7 +2068,7 @@ private bool TryOpen(TaskCompletionSource retry, SqlConnec bool result = false; - _applyTransientFaultHandling = (!overrides.HasFlag(SqlConnectionOverrides.OpenWithoutRetry) && retry == null && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); + _applyTransientFaultHandling = (!overrides.HasFlag(SqlConnectionOverrides.OpenWithoutRetry) && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); if (connectionOptions != null && (connectionOptions.Authentication == SqlAuthenticationMethod.SqlPassword || @@ -2111,7 +2111,7 @@ private bool TryOpen(TaskCompletionSource retry, SqlConnec } // Set future transient fault handling based on connection options - _applyTransientFaultHandling = (retry == null && connectionOptions != null && connectionOptions.ConnectRetryCount > 0); + _applyTransientFaultHandling = connectionOptions != null && connectionOptions.ConnectRetryCount > 0; return result; } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs index 039bf2f766..e61bdfe4ac 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs @@ -7,6 +7,7 @@ using System.Data.Common; using System.Reflection; using System.Security; +using System.Threading.Tasks; using Microsoft.SqlServer.TDS.Servers; using Xunit; @@ -34,6 +35,26 @@ public void IntegratedAuthConnectionTest() connection.Open(); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] + [InlineData(40613)] + [InlineData(42108)] + [InlineData(42109)] + [PlatformSpecific(TestPlatforms.Windows)] + public async Task TransientFaultTestAsync(uint errorCode) + { + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + SqlConnectionStringBuilder builder = new() + { + DataSource = "localhost," + server.Port, + IntegratedSecurity = true, + Encrypt = SqlConnectionEncryptOption.Optional + }; + + using SqlConnection connection = new(builder.ConnectionString); + await connection.OpenAsync(); + Assert.Equal(ConnectionState.Open, connection.State); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] [InlineData(40613)] [InlineData(42108)] @@ -57,14 +78,70 @@ public void TransientFaultTest(uint errorCode) } catch (Exception e) { - if (null != connection) - { - Assert.Equal(ConnectionState.Closed, connection.State); - } Assert.False(true, e.Message); } } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] + [InlineData(40613)] + [InlineData(42108)] + [InlineData(42109)] + [PlatformSpecific(TestPlatforms.Windows)] + public async Task TransientFaultDisabledTestAsync(uint errorCode) + { + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + SqlConnectionStringBuilder builder = new() + { + DataSource = "localhost," + server.Port, + IntegratedSecurity = true, + ConnectRetryCount = 0, + Encrypt = SqlConnectionEncryptOption.Optional + }; + + using SqlConnection connection = new(builder.ConnectionString); + try + { + await connection.OpenAsync(); + Assert.False(true, "Connection should not have opened."); + } + catch (SqlException e) + { + // FATAL Error, should result in closed connection. + Assert.Equal(20, e.Class); + Assert.Equal(ConnectionState.Closed, connection.State); + } + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotArmProcess))] + [InlineData(40613)] + [InlineData(42108)] + [InlineData(42109)] + [PlatformSpecific(TestPlatforms.Windows)] + public void TransientFaultDisabledTest(uint errorCode) + { + using TransientFaultTDSServer server = TransientFaultTDSServer.StartTestServer(true, true, errorCode); + SqlConnectionStringBuilder builder = new() + { + DataSource = "localhost," + server.Port, + IntegratedSecurity = true, + ConnectRetryCount = 0, + Encrypt = SqlConnectionEncryptOption.Optional + }; + + using SqlConnection connection = new(builder.ConnectionString); + try + { + connection.Open(); + Assert.False(true, "Connection should not have opened."); + } + catch (SqlException e) + { + // FATAL Error, should result in closed connection. + Assert.Equal(20, e.Class); + Assert.Equal(ConnectionState.Closed, connection.State); + } + } + [Fact] public void SqlConnectionDbProviderFactoryTest() { diff --git a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs index 419f7e5d24..eda4de8e2a 100644 --- a/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs +++ b/src/Microsoft.Data.SqlClient/tests/tools/TDS/TDS.Servers/TransientFaultTDSServer.cs @@ -146,6 +146,7 @@ private void Dispose(bool isDisposing) if (isDisposing) { _endpoint?.Stop(); + RequestCounter = 0; } } }