Commit 5fb3279a authored by Marc Gravell's avatar Marc Gravell

add `isInitialConnect` override to make sure we record failure in the initial connect

parent 3cd098b4
using System;
using System.Security.Authentication;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
......@@ -32,10 +33,16 @@ public async Task SSLCertificateValidationError(bool isCertValidationSucceeded)
if (!isCertValidationSucceeded)
{
//validate that in this case it throws an certificatevalidation exception
var ex = Assert.Throws<RedisConnectionException>(() => connection.GetDatabase().Ping());
var rde = (RedisConnectionException)ex.InnerException;
Assert.Equal(ConnectionFailureType.AuthenticationFailure, rde.FailureType);
Assert.Equal("The remote certificate is invalid according to the validation procedure.", rde.InnerException.Message);
var outer = Assert.Throws<RedisConnectionException>(() => connection.GetDatabase().Ping());
Assert.Equal(ConnectionFailureType.UnableToResolvePhysicalConnection, outer.FailureType);
Assert.NotNull(outer.InnerException);
var inner = Assert.IsType<RedisConnectionException>(outer.InnerException);
Assert.Equal(ConnectionFailureType.AuthenticationFailure, inner.FailureType);
Assert.NotNull(inner.InnerException);
var innerMost = Assert.IsType<AuthenticationException>(inner.InnerException);
Assert.Equal("The remote certificate is invalid according to the validation procedure.", innerMost.Message);
}
else
{
......@@ -80,15 +87,20 @@ public void SocketFailureError()
options.Ssl = true;
options.Password = "";
options.AbortOnConnectFail = false;
var ex = Assert.Throws<RedisConnectionException>(() =>
options.ConnectTimeout = 1000;
var outer = Assert.Throws<RedisConnectionException>(() =>
{
using (var muxer = ConnectionMultiplexer.Connect(options))
{
muxer.GetDatabase().Ping();
}
});
var rde = (RedisConnectionException)ex.InnerException;
Assert.Equal(ConnectionFailureType.SocketFailure, rde.FailureType);
Assert.Equal(ConnectionFailureType.UnableToResolvePhysicalConnection, outer.FailureType);
Assert.NotNull(outer.InnerException);
var inner = Assert.IsType<RedisConnectionException>(outer.InnerException);
Assert.Equal(ConnectionFailureType.UnableToConnect, inner.FailureType);
}
#if DEBUG // needs AllowConnect, which is DEBUG only
[Fact]
......
......@@ -159,7 +159,7 @@ internal async void BeginConnectAsync(TextWriter log)
catch (ObjectDisposedException)
{
bridge.Multiplexer.LogLocked(log, "(socket shutdown)");
try { Error(); }
try { RecordConnectionFailed(ConnectionFailureType.UnableToConnect, isInitialConnect: true); }
catch (Exception inner)
{
ConnectionMultiplexer.TraceWithoutContext(inner.Message);
......@@ -168,7 +168,7 @@ internal async void BeginConnectAsync(TextWriter log)
catch (Exception outer)
{
ConnectionMultiplexer.TraceWithoutContext(outer.Message);
try { Error(); }
try { RecordConnectionFailed(ConnectionFailureType.UnableToConnect, isInitialConnect: true); }
catch (Exception inner)
{
ConnectionMultiplexer.TraceWithoutContext(inner.Message);
......@@ -290,13 +290,13 @@ public Task FlushAsync()
return Task.CompletedTask;
}
public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null)
public void RecordConnectionFailed(ConnectionFailureType failureType, Exception innerException = null, [CallerMemberName] string origin = null, bool isInitialConnect = false)
{
Exception outerException = innerException;
IdentifyFailureType(innerException, ref failureType);
if (_ioPipe != null) // if *we* didn't burn the pipe: flag it
if (_ioPipe != null || isInitialConnect) // if *we* didn't burn the pipe: flag it
{
if (failureType == ConnectionFailureType.InternalFailure) OnInternalError(innerException, origin);
......@@ -1133,7 +1133,7 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc
}
catch (AuthenticationException authexception)
{
RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, authexception);
RecordConnectionFailed(ConnectionFailureType.AuthenticationFailure, authexception, isInitialConnect: true);
bridge.Multiplexer.Trace("Encryption failure");
return false;
}
......@@ -1154,17 +1154,12 @@ internal async ValueTask<bool> ConnectedAsync(Socket socket, TextWriter log, Soc
}
catch (Exception ex)
{
RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex); // includes a bridge.OnDisconnected
RecordConnectionFailed(ConnectionFailureType.InternalFailure, ex, isInitialConnect: true); // includes a bridge.OnDisconnected
bridge.Multiplexer.Trace("Could not connect: " + ex.Message, physicalName);
return false;
}
}
internal void Error()
{
RecordConnectionFailed(ConnectionFailureType.SocketFailure);
}
private void MatchResult(RawResult result)
{
var muxer = BridgeCouldBeNull?.Multiplexer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment