Skip to content

Commit

Permalink
Merged PR 4035: [5.1.2] | Fix Transient fault handling issue with Ope…
Browse files Browse the repository at this point in the history
…nAsync (dotnet#1983)

Ports [dotnet#1983](dotnet#1983)
  • Loading branch information
DavoudEshtehari committed Oct 16, 2023
1 parent 39cedc8 commit 80d1f47
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
Expand Up @@ -1820,7 +1820,7 @@ private bool TryOpen(TaskCompletionSource<DbConnectionInternal> 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 ||
Expand Down Expand Up @@ -1849,7 +1849,7 @@ private bool TryOpen(TaskCompletionSource<DbConnectionInternal> 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;

Expand Down
Expand Up @@ -2059,7 +2059,7 @@ private bool TryOpen(TaskCompletionSource<DbConnectionInternal> 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 ||
Expand Down Expand Up @@ -2102,7 +2102,7 @@ private bool TryOpen(TaskCompletionSource<DbConnectionInternal> 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;
}
Expand Down
Expand Up @@ -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;

Expand Down Expand Up @@ -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)]
Expand All @@ -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()
{
Expand Down
Expand Up @@ -146,6 +146,7 @@ private void Dispose(bool isDisposing)
if (isDisposing)
{
_endpoint?.Stop();
RequestCounter = 0;
}
}
}
Expand Down

0 comments on commit 80d1f47

Please sign in to comment.