Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass AccessMode in BEGIN and RUN messages #335

Merged
merged 1 commit into from
Mar 1, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Pass AccessMode in BEGIN and RUN messages
No `mode` parameter in statement metadata means that the access mode set by client is `Write`, whereas a value of `r` means it is set as `Read`.
ali-ince committed Feb 7, 2019
commit a77a6d5aaccd2ae343d42eae7e120d6bf0940980
95 changes: 68 additions & 27 deletions Neo4j.Driver/Neo4j.Driver.Tests/ConnectionPoolTests.cs
Original file line number Diff line number Diff line change
@@ -71,8 +71,8 @@ public void ShouldBlockWhenMaxPoolSizeReached()
pool.NumberOfInUseConnections.Should().Be(2);

var timer = new Stopwatch();
var blockingAcquire = new Task(()=>{ pool.Acquire(); });
var releaseConn = new Task(()=>{ conn.Close(); });
var blockingAcquire = new Task(() => { pool.Acquire(); });
var releaseConn = new Task(() => { conn.Close(); });

timer.Start();
blockingAcquire.Start();
@@ -163,7 +163,6 @@ public void ShouldCreateNewWhenQueueIsEmpty()
[Fact]
public void ShouldCloseConnectionIfFailedToCreate()
{

var connMock = new Mock<IPooledConnection>();
connMock.Setup(x => x.Init()).Throws(new NotImplementedException());

@@ -298,7 +297,8 @@ public void ShouldReuseIdleNotTooLongConn()
conns.Add(mock.Object);
var enableIdleTooLongTest = TimeSpan.FromMilliseconds(100);
var poolSettings = new ConnectionPoolSettings(
new Config {
new Config
{
MaxIdleConnectionPoolSize = 2,
ConnectionIdleTimeout = enableIdleTooLongTest,
MaxConnectionLifetime = Config.InfiniteInterval, // disable life time check
@@ -452,7 +452,6 @@ public void ShouldTimeoutAfterAcquireTimeoutIfPoolIsFull()
stopWatch.Elapsed.TotalSeconds.Should().BeGreaterOrEqualTo(10, 0.1);
exception.Message.Should().StartWith("Failed to obtain a connection from pool within");
exception.Should().BeOfType<ClientException>();

}

[Fact]
@@ -504,14 +503,54 @@ public async void ShouldTimeoutAfterAcquireAsyncTimeoutWhenConnectionIsNotValida
.ToConfig();


var pool = NewConnectionPool(poolSettings: new ConnectionPoolSettings(config), isConnectionValid: false);
var pool = NewConnectionPool(poolSettings: new ConnectionPoolSettings(config),
isConnectionValid: false);

var exception = await Record.ExceptionAsync(() => pool.AcquireAsync(AccessMode.Read));

exception.Should().BeOfType<ClientException>();
exception.Message.Should().StartWith("Failed to obtain a connection from pool within");
}

[Theory]
[InlineData(AccessMode.Read)]
[InlineData(AccessMode.Write)]
public void ShouldManageModeProperty(AccessMode mode)
{
var connection = new Mock<IPooledConnection>().SetupProperty(x => x.Mode);
var idleConnections = new BlockingCollection<IPooledConnection>() { connection.Object };

var pool = NewConnectionPool(idleConnections);

var acquired = pool.Acquire(mode);
acquired.Mode.Should().Be(mode);

pool.Release((IPooledConnection)acquired);
acquired.Mode.Should().BeNull();

connection.VerifySet(x => x.Mode = mode);
connection.VerifySet(x => x.Mode = null);
}

[Theory]
[InlineData(AccessMode.Read)]
[InlineData(AccessMode.Write)]
public async Task ShouldManageModePropertyAsync(AccessMode mode)
{
var connection = new Mock<IPooledConnection>().SetupProperty(x => x.Mode);
var idleConnections = new BlockingCollection<IPooledConnection>() { connection.Object };

var pool = NewConnectionPool(idleConnections);

var acquired = await pool.AcquireAsync(mode);
acquired.Mode.Should().Be(mode);

await pool.ReleaseAsync((IPooledConnection)acquired);
acquired.Mode.Should().BeNull();

connection.VerifySet(x => x.Mode = mode);
connection.VerifySet(x => x.Mode = null);
}
}

public class ReleaseMethod
@@ -733,8 +772,8 @@ public void ShouldReleaseAll()

pool.NumberOfIdleConnections.Should().Be(0);
pool.NumberOfInUseConnections.Should().Be(0);
mock.Verify(x=>x.Destroy(), Times.Once);
mock1.Verify(x=>x.Destroy(), Times.Once);
mock.Verify(x => x.Destroy(), Times.Once);
mock1.Verify(x => x.Destroy(), Times.Once);
}

[Fact]
@@ -804,7 +843,8 @@ public class NumberOfInUseConnections
public void ShouldReturnZeroAfterCreation()
{
var uri = new Uri("bolt://localhost:7687");
var poolSettings = new ConnectionPoolSettings(1, 1, Config.InfiniteInterval, Config.InfiniteInterval, Config.InfiniteInterval);
var poolSettings = new ConnectionPoolSettings(1, 1, Config.InfiniteInterval, Config.InfiniteInterval,
Config.InfiniteInterval);
var logger = new Mock<IDriverLogger>().Object;
var connFactory = new MockedConnectionFactory();

@@ -871,10 +911,10 @@ public void ShouldReturnCorrectCountWhenBothIdleAndInUseConnectionsPresent()

public class PoolSize
{

private static ConnectionPool CreatePool(IConnection conn, int maxIdlePoolSize, int maxPoolSize)
{
var poolSettings = new ConnectionPoolSettings(maxIdlePoolSize, maxPoolSize, Config.InfiniteInterval, Config.InfiniteInterval, Config.InfiniteInterval);
var poolSettings = new ConnectionPoolSettings(maxIdlePoolSize, maxPoolSize, Config.InfiniteInterval,
Config.InfiniteInterval, Config.InfiniteInterval);
var connFactory = new MockedConnectionFactory(conn);

var pool = new ConnectionPool(connFactory, poolSettings: poolSettings);
@@ -963,7 +1003,8 @@ public void ShouldReportPoolSizeCorrectOnConcurrentRequests()
var stopMarker = 0;
var waitedTime = 0;

var acquireTasks = Enumerable.Range(0, 100).Select(i => Task.Run(() => {
var acquireTasks = Enumerable.Range(0, 100).Select(i => Task.Run(() =>
{
var conn = pool.Acquire();
Interlocked.Increment(ref acquireCounter);

@@ -1077,7 +1118,8 @@ public async void ShouldReportPoolSizeCorrectOnConcurrentRequestsAsync()
var stopMarker = 0;
var waitedTime = 0;

var acquireTasks = Enumerable.Range(0, 100).Select(i => Task.Run(async () => {
var acquireTasks = Enumerable.Range(0, 100).Select(i => Task.Run(async () =>
{
var conn = await pool.AcquireAsync(AccessMode.Read);
Interlocked.Increment(ref acquireCounter);

@@ -1110,7 +1152,6 @@ public async void ShouldReportPoolSizeCorrectOnConcurrentRequestsAsync()
reportedSizes.Should().NotContain(v => v < 0);
reportedSizes.Should().NotContain(v => v > 5);
}

}

public class PoolState
@@ -1171,7 +1212,7 @@ public void FromInactiveViaAcquireThrowsError()
var pool = NewConnectionPool();
pool.Status = ConnectionPoolStatus.Inactive;

var exception = Record.Exception(()=>pool.Acquire());
var exception = Record.Exception(() => pool.Acquire());

exception.Should().BeOfType<ClientException>();
pool.Status.Should().Be(ConnectionPoolStatus.Inactive);
@@ -1236,7 +1277,7 @@ public void FromClosedViaAcquireThrowsError()
var pool = NewConnectionPool();
pool.Status = ConnectionPoolStatus.Closed;

var exception = Record.Exception(()=>pool.Acquire());
var exception = Record.Exception(() => pool.Acquire());

exception.Should().BeOfType<ObjectDisposedException>();
pool.Status.Should().Be(ConnectionPoolStatus.Closed);
@@ -1307,6 +1348,7 @@ private static List<Mock<IPooledConnection>> FillIdleConnections(
idleMocks.Add(connMock);
idleConnections.Add(connMock.Object);
}

return idleMocks;
}

@@ -1320,30 +1362,31 @@ private static List<Mock<IPooledConnection>> FillInUseConnections(
inUseMocks.Add(connMock);
inUseConnections.TryAdd(connMock.Object);
}

return inUseMocks;
}

private static void VerifyDestroyCalledOnce(List<Mock<IPooledConnection>> mocks)
{
foreach (var conn in mocks)
{
conn.Verify(x=>x.Destroy(), Times.Once);
conn.Verify(x => x.Destroy(), Times.Once);
}
}

private static void VerifyDestroyAsyncCalledOnce(List<Mock<IPooledConnection>> mocks)
{
foreach (var conn in mocks)
{
conn.Verify(x=>x.DestroyAsync(), Times.Once);
conn.Verify(x => x.DestroyAsync(), Times.Once);
}
}

[Fact]
public void ShouldCloseAllIdleConnections()
{
// Given
var idleConnections = new BlockingCollection<IPooledConnection> ();
var idleConnections = new BlockingCollection<IPooledConnection>();
var idleMocks = FillIdleConnections(idleConnections, 10);
var pool = NewConnectionPool(idleConnections);

@@ -1359,7 +1402,7 @@ public void ShouldCloseAllIdleConnections()
public async Task ShouldCloseAllIdleConnectionsAsync()
{
// Given
var idleConnections = new BlockingCollection<IPooledConnection> ();
var idleConnections = new BlockingCollection<IPooledConnection>();

var idleMocks = FillIdleConnections(idleConnections, 10);

@@ -1502,10 +1545,7 @@ public void ShouldCloseAllIdleConnectionsRegardlessActivateCalled()

var specialConn = new Mock<IPooledConnection>();
var pool = NewConnectionPool(idleConnections);
specialConn.Setup(x => x.Destroy()).Callback(() =>
{
pool.Activate();
});
specialConn.Setup(x => x.Destroy()).Callback(() => { pool.Activate(); });

idleConnections.Add(specialConn.Object);
idleMocks.Add(specialConn);
@@ -1555,7 +1595,9 @@ public MockedConnectionFactory(IConnection conn = null)
{
_connection = conn ?? new Mock<IConnection>().Object;
}
public IPooledConnection Create(Uri uri, IConnectionReleaseManager releaseManager, IConnectionListener listener)

public IPooledConnection Create(Uri uri, IConnectionReleaseManager releaseManager,
IConnectionListener listener)
{
return new PooledConnection(_connection, releaseManager, listener);
}
@@ -1569,7 +1611,6 @@ private static ConnectionPool NewConnectionPool(
{
return new ConnectionPool(new MockedConnectionFactory(), idleConnections, inUseConnections,
poolSettings, new TestConnectionValidator(isConnectionValid));

}

private static ConnectionPool NewConnectionPoolWithConnectionTimeoutCheckDisabled(
@@ -1600,4 +1641,4 @@ private static ITimer MockedTimer
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
using Moq;
using Neo4j.Driver.Internal;
using Neo4j.Driver.Internal.Connector;
using Neo4j.Driver.V1;
using Xunit;

namespace Neo4j.Driver.Tests.Connector
@@ -69,7 +70,7 @@ public async void ShouldHandleBaseErrorForFaultedTask()
var connMock = new Mock<IConnection>();
var conn = new TestDelegatedConnection(connMock.Object);

await Record.ExceptionAsync(()=>conn.TaskWithErrorHandling(FaultedTask));
await Record.ExceptionAsync(() => conn.TaskWithErrorHandling(FaultedTask));

conn.ErrorList.Count.Should().Be(1);
conn.ErrorList[0].Should().BeOfType<InvalidOperationException>();
@@ -83,13 +84,45 @@ public async void ShouldHandleBaseErrorForFaultedOutsideTask()
var conn = new TestDelegatedConnection(connMock.Object);

FaultedTask().IsFaulted.Should().BeTrue();
await Record.ExceptionAsync(()=>conn.TaskWithErrorHandling(FaultedOutsideTask));
await Record.ExceptionAsync(() => conn.TaskWithErrorHandling(FaultedOutsideTask));

conn.ErrorList.Count.Should().Be(1);
conn.ErrorList[0].Should().BeOfType<InvalidOperationException>();
conn.ErrorList[0].Message.Should().Be("Molly ate too much today!");
}
}

public class ModeProperty
{
[Theory]
[InlineData(AccessMode.Read)]
[InlineData(AccessMode.Write)]
public void ShouldGetModeFromDelegate(AccessMode mode)
{
var connMock = new Mock<IConnection>();
connMock.Setup(x => x.Mode).Returns(mode);

var delegateConnection = new TestDelegatedConnection(connMock.Object);

delegateConnection.Mode.Should().Be(mode);

connMock.VerifyGet(x => x.Mode);
}

[Theory]
[InlineData(AccessMode.Read)]
[InlineData(AccessMode.Write)]
public void ShouldSetModeOnDelegate(AccessMode mode)
{
var connMock = new Mock<IConnection>();
connMock.Setup(x => x.Mode).Returns(mode);

var delegateConnection = new TestDelegatedConnection(connMock.Object);

delegateConnection.Mode = mode;

connMock.VerifySet(c => c.Mode = mode);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -56,7 +56,7 @@ public void ShouldWrite()
new Dictionary<string, object>
{
{"username", "MollyMostlyWhite"}
}));
}, AccessMode.Write));

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var reader = readerMachine.Reader();
@@ -85,7 +85,7 @@ public void ShouldWriteEmptyMapWhenMetadataIsNull()
var writerMachine = CreateWriterMachine();
var writer = writerMachine.Writer();

writer.Write(new BeginMessage(null, null));
writer.Write(new BeginMessage(null, null, AccessMode.Write));

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var reader = readerMachine.Reader();
Original file line number Diff line number Diff line change
@@ -62,7 +62,7 @@ public void ShouldWrite()
new Dictionary<string, object>
{
{"username", "MollyMostlyWhite"}
}));
}, AccessMode.Write));

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var reader = readerMachine.Reader();
@@ -98,7 +98,7 @@ public void ShouldWriteEmptyMapWhenParamsAndMetadataAreNull()
var writerMachine = CreateWriterMachine();
var writer = writerMachine.Writer();

writer.Write(new RunWithMetadataMessage(new Statement("RETURN 1")));
writer.Write(new RunWithMetadataMessage(new Statement("RETURN 1"), AccessMode.Write));

var readerMachine = CreateReaderMachine(writerMachine.GetOutput());
var reader = readerMachine.Reader();
Loading