Skip to content

Commit

Permalink
Added basic error handling callback
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhen Li committed Oct 27, 2016
1 parent 17765b2 commit d143b54
Show file tree
Hide file tree
Showing 28 changed files with 508 additions and 382 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,12 +87,9 @@ public void WhenISetUpADriverToAnIncorrectPort()
[When(@"I set up a driver with wrong scheme")]
public void WhenISetUpADriverWithWrongScheme()
{
using (var driver = GraphDatabase.Driver("http://localhost"))
{
var ex = Xunit.Record.Exception(() => driver.Session());
ex.Should().BeOfType<NotSupportedException>();
ex.Message.Should().Be("Unsupported protocol: http");
}
var ex = Xunit.Record.Exception(() => GraphDatabase.Driver("http://localhost"));
ex.Should().BeOfType<NotSupportedException>();
ex.Message.Should().Be("Unsupported URI scheme: http");
}

[Then(@"it throws a `ClientException`")]
Expand Down
42 changes: 21 additions & 21 deletions Neo4j.Driver/Neo4j.Driver.Tests/ConnectionPoolTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ private IConnection MockedConnection
get
{
var mock = new Mock<IConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
return mock.Object;
}
}
Expand Down Expand Up @@ -116,7 +116,7 @@ public void ShouldCreateNewWhenQueueOnlyContainsUnhealthyConnections()
var conns = new Queue<IPooledConnection>();
var unhealthyId = Guid.NewGuid();
var unhealthyMock = new Mock<IPooledConnection>();
unhealthyMock.Setup(x => x.IsHealthy).Returns(false);
unhealthyMock.Setup(x => x.IsOpen).Returns(false);
unhealthyMock.Setup(x => x.Id).Returns(unhealthyId);

conns.Enqueue(unhealthyMock.Object);
Expand All @@ -129,7 +129,7 @@ public void ShouldCreateNewWhenQueueOnlyContainsUnhealthyConnections()

pool.NumberOfAvailableConnections.Should().Be(0);
pool.NumberOfInUseConnections.Should().Be(1);
unhealthyMock.Verify(x => x.IsHealthy, Times.Once);
unhealthyMock.Verify(x => x.IsOpen, Times.Once);
unhealthyMock.Verify(x => x.Close(), Times.Once);

conn.Should().NotBeNull();
Expand All @@ -141,7 +141,7 @@ public void ShouldReuseOldWhenReusableConnectionInQueue()
{
var conns = new Queue<IPooledConnection>();
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);

conns.Enqueue(mock.Object);
var pool = new ConnectionPool(MockedConnection, conns);
Expand All @@ -153,7 +153,7 @@ public void ShouldReuseOldWhenReusableConnectionInQueue()

pool.NumberOfAvailableConnections.Should().Be(0);
pool.NumberOfInUseConnections.Should().Be(1);
mock.Verify(x => x.IsHealthy, Times.Once);
mock.Verify(x => x.IsOpen, Times.Once);
conn.Should().Be(mock.Object);
}

Expand All @@ -162,9 +162,9 @@ public void ShouldReuseReusableWhenReusableConnectionInQueue()
{
var conns = new Queue<IPooledConnection>();
var healthyMock = new Mock<IPooledConnection>();
healthyMock.Setup(x => x.IsHealthy).Returns(true);
healthyMock.Setup(x => x.IsOpen).Returns(true);
var unhealthyMock = new Mock<IPooledConnection>();
unhealthyMock.Setup(x => x.IsHealthy).Returns(false);
unhealthyMock.Setup(x => x.IsOpen).Returns(false);

conns.Enqueue(unhealthyMock.Object);
conns.Enqueue(healthyMock.Object);
Expand Down Expand Up @@ -201,7 +201,7 @@ public void ShouldAcquireNewWhenBeingUsedConcurrentlyBy(int numberOfThreads)
for (var i = 0; i < numberOfThreads; i++)
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
mock.Setup(x => x.Id).Returns(ids[i]);
conns.Enqueue(mock.Object);
mockConns.Enqueue(mock);
Expand Down Expand Up @@ -246,7 +246,7 @@ public void ShouldAcquireNewWhenBeingUsedConcurrentlyBy(int numberOfThreads)

foreach (var mock in mockConns)
{
mock.Verify(x => x.IsHealthy, Times.Once);
mock.Verify(x => x.IsOpen, Times.Once);
}
}

Expand Down Expand Up @@ -277,7 +277,7 @@ public void ShouldCloseAcquiredConnectionIfPoolDisposeStarted()
// This is to simulate Acquire called first,
// but before Acquire put a new conn into inUseConn, Dispose get called.
// Note: Once dispose get called, it is forbiden to put anything into queue.
healthyMock.Setup(x => x.IsHealthy).Returns(true)
healthyMock.Setup(x => x.IsOpen).Returns(true)
.Callback(() => pool.DisposeCalled = true); // Simulte Dispose get called at this time
conns.Enqueue(healthyMock.Object);
pool.NumberOfAvailableConnections.Should().Be(1);
Expand All @@ -286,7 +286,7 @@ public void ShouldCloseAcquiredConnectionIfPoolDisposeStarted()

pool.NumberOfAvailableConnections.Should().Be(0);
pool.NumberOfInUseConnections.Should().Be(0);
healthyMock.Verify(x => x.IsHealthy, Times.Once);
healthyMock.Verify(x => x.IsOpen, Times.Once);
healthyMock.Verify(x => x.Close(), Times.Once);
exception.Should().BeOfType<InvalidOperationException>();
exception.Message.Should().Contain("the driver has already started to dispose");
Expand All @@ -299,7 +299,7 @@ public class ReleaseMethod
public void ShouldReturnToPoolWhenConnectionIsReusableAndPoolIsNotFull()
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
var id = new Guid();

var inUseconns = new Dictionary<Guid, IPooledConnection>();
Expand All @@ -319,7 +319,7 @@ public void ShouldReturnToPoolWhenConnectionIsReusableAndPoolIsNotFull()
public void ShouldCloseConnectionWhenConnectionIsUnhealthy()
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(false);
mock.Setup(x => x.IsOpen).Returns(false);
var id = new Guid();

var inUseConns = new Dictionary<Guid, IPooledConnection>();
Expand All @@ -337,10 +337,10 @@ public void ShouldCloseConnectionWhenConnectionIsUnhealthy()
}

[Fact]
public void ShouldCloseConnectionWhenConnectionIsHealthyButNotResetable()
public void ShouldCloseConnectionWhenConnectionIsOpenButNotResetable()
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
mock.Setup(x => x.ClearConnection()).Throws<ClientException>();
var id = new Guid();

Expand All @@ -362,7 +362,7 @@ public void ShouldCloseConnectionWhenConnectionIsHealthyButNotResetable()
public void ShouldCloseTheConnectionIfSessionIsReusableButThePoolIsFull()
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
var id = new Guid();

var inUseConns = new Dictionary<Guid, IPooledConnection>();
Expand Down Expand Up @@ -408,7 +408,7 @@ public void ShouldCloseConnectionIfPoolDisposeStarted()
// this is to simulate Release called first,
// but before Release put a new conn into availConns, Dispose get called.
// Note: Once dispose get called, it is forbiden to put anything into queue.
mock.Setup(x => x.IsHealthy).Returns(true)
mock.Setup(x => x.IsOpen).Returns(true)
.Callback(() => pool.DisposeCalled = true); // Simulte Dispose get called at this time
pool.Release(id);

Expand All @@ -425,14 +425,14 @@ public class DisposeMethod
public void ShouldReleaseAll()
{
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
var id = Guid.NewGuid();
var inUseConns = new Dictionary<Guid, IPooledConnection>();
inUseConns.Add(id, mock.Object);

var availableConns = new Queue<IPooledConnection>();
var mock1 = new Mock<IPooledConnection>();
mock1.Setup(x => x.IsHealthy).Returns(true);
mock1.Setup(x => x.IsOpen).Returns(true);

availableConns.Enqueue(mock1.Object);

Expand All @@ -451,14 +451,14 @@ public void ShouldLogInUseAndAvailableConnectionIds()
{
var mockLogger = new Mock<ILogger>();
var mock = new Mock<IPooledConnection>();
mock.Setup(x => x.IsHealthy).Returns(true);
mock.Setup(x => x.IsOpen).Returns(true);
var id = Guid.NewGuid();
var inUseConns = new Dictionary<Guid, IPooledConnection>();
inUseConns.Add(id, mock.Object);

var availableConns = new Queue<IPooledConnection>();
var mock1 = new Mock<IPooledConnection>();
mock1.Setup(x => x.IsHealthy).Returns(true);
mock1.Setup(x => x.IsOpen).Returns(true);

availableConns.Enqueue(mock1.Object);

Expand Down
21 changes: 11 additions & 10 deletions Neo4j.Driver/Neo4j.Driver.Tests/Connector/SocketConnectionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,15 @@ public void ShouldNotClearMessagesResponseHandlerAndEnqueueResetMessage()
}
}

// TODO move this to PooledConnectionTests
public class HasUnrecoverableError
{
[Fact]
public void ShouldReportErrorIfIsTransientException()
{
var mock = MockSocketClient;
var mockResponseHandler = new Mock<IMessageResponseHandler>();
var con = new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
var con = new PooledConnection (new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object));

mockResponseHandler.Setup(x => x.Error).Returns(new TransientException("BLAH", "lalala"));
con.HasUnrecoverableError.Should().BeFalse();
Expand All @@ -212,7 +213,7 @@ public void ShouldReportErrorIfIsDatabaseException()
{
var mock = MockSocketClient;
var mockResponseHandler = new Mock<IMessageResponseHandler>();
var con = new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
var con = new PooledConnection(new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object));

mockResponseHandler.Setup(x => x.HasError).Returns(true);
mockResponseHandler.Setup(x => x.Error).Returns(new DatabaseException("BLAH", "lalala"));
Expand All @@ -230,14 +231,14 @@ public void ShouldNotReportErrorIfIsOtherExceptions()
{
var mock = MockSocketClient;
var mockResponseHandler = new Mock<IMessageResponseHandler>();
var con = new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
var con = new PooledConnection(new SocketConnection(mock.Object, AuthTokens.None, Logger, mockResponseHandler.Object));

mockResponseHandler.Setup(x => x.Error).Returns(new ClientException("BLAH", "lalala"));
con.HasUnrecoverableError.Should().BeFalse();
}
}

public class IsHealthyMethod
public class IsOpenMethod
{
[Fact]
public void ShouldBeFalseWhenConectionIsNotOpen()
Expand All @@ -247,8 +248,8 @@ public void ShouldBeFalseWhenConectionIsNotOpen()
var mockResponseHandler = new Mock<IMessageResponseHandler>();
mockResponseHandler.Setup(x => x.Error).Returns(new ClientException()); // has no unrecoverable error

var conn = new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
conn.IsHealthy.Should().BeFalse();
var conn = new PooledConnection(new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object));
conn.IsOpen.Should().BeFalse();
}

[Fact]
Expand All @@ -259,8 +260,8 @@ public void ShouldBeFalseWhenConnectionHasUnrecoverableError()
var mockResponseHandler = new Mock<IMessageResponseHandler>();
mockResponseHandler.Setup(x => x.Error).Returns(new DatabaseException()); // unrecoverable error

var conn = new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
conn.IsHealthy.Should().BeFalse();
var conn = new PooledConnection(new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object));
conn.IsOpen.Should().BeFalse();
}

[Fact]
Expand All @@ -271,8 +272,8 @@ public void ShouldReturnTrueWhenIsHealthy()
var mockResponseHandler = new Mock<IMessageResponseHandler>();
mockResponseHandler.Setup(x => x.Error).Returns(new ClientException()); // has no unrecoverable error

var conn = new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object);
conn.IsHealthy.Should().BeTrue();
var conn = new PooledConnection(new SocketConnection(mockClient.Object, AuthTokens.None, Logger, mockResponseHandler.Object));
conn.IsOpen.Should().BeTrue();
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions Neo4j.Driver/Neo4j.Driver.Tests/Neo4j.Driver.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@
</Choose>
<ItemGroup>
<Compile Include="AuthTokenTests.cs" />
<Compile Include="ClusterServerPoolTests.cs" />
<Compile Include="ConcurrentRoundRobinQueueTests.cs" />
<Compile Include="Routing\ClusterConnectionPoolTests.cs" />
<Compile Include="Routing\ConcurrentRoundRobinSetTests.cs" />
<Compile Include="ConfigTests.cs" />
<Compile Include="Connector\ChunkedOutputTest.cs" />
<Compile Include="Connector\MessageResponseHandlerTests.cs" />
Expand Down
Loading

0 comments on commit d143b54

Please sign in to comment.