public void ForgetConnection_ExceedPoolSize_GetConnectionShouldBlockAndReturnNewConnection() { // Arrange var pool = new SapConnectionPool( ConnectionParameters, poolSize: 1, connectionFactory: _ => Mock.Of <ISapConnection>()); ISapConnection connection1 = pool.GetConnection(); // Act Task.Run(async() => { await Task.Delay(150); pool.ForgetConnection(connection1); }); var sw = new Stopwatch(); sw.Start(); ISapConnection connection2 = pool.GetConnection(); sw.Stop(); // Assert sw.ElapsedMilliseconds.Should().BeGreaterThan(100); connection2.Should().NotBeNull(); connection2.Should().NotBe(connection1); }
public void GetConnection_ShouldOpenConnection() { // Arrange var connectionMock = new Mock <ISapConnection>(); var pool = new SapConnectionPool(ConnectionParameters, connectionFactory: _ => connectionMock.Object); // Act ISapConnection connection = pool.GetConnection(); // Assert connection.Should().Be(connectionMock.Object); connectionMock.Verify(x => x.Connect(), Times.Once); }
public void ForgetConnection_ShouldDisposeConnection() { // Arrange var connectionMock = new Mock <ISapConnection>(); var pool = new SapConnectionPool(ConnectionParameters, connectionFactory: _ => connectionMock.Object); ISapConnection connection = pool.GetConnection(); // Act pool.ForgetConnection(connection); // Assert connectionMock.Verify(x => x.Dispose(), Times.Once); }
/// <summary> /// Returns the underlying <see cref="SapConnection"/> to the connection pool and make it available for reuse. /// </summary> public void Dispose() { if (_disposed) { return; } if (_connection != null) { _pool.ReturnConnection(_connection); _connection = null; } _disposed = true; }
public void GetConnection_ShouldReturnDifferentConnectionsUpToPoolSize() { // Arrange var pool = new SapConnectionPool( ConnectionParameters, poolSize: 2, connectionFactory: _ => Mock.Of <ISapConnection>()); // Act ISapConnection connection1 = pool.GetConnection(); ISapConnection connection2 = pool.GetConnection(); // Assert connection1.Should().NotBeNull(); connection2.Should().NotBeNull(); connection1.Should().NotBe(connection2); }
public void Dispose_ShouldDisposeIdleConnections() { // Arrange var connectionMock = new Mock <ISapConnection>(); var pool = new SapConnectionPool(ConnectionParameters, connectionFactory: _ => connectionMock.Object); ISapConnection connection1 = pool.GetConnection(); ISapConnection connection2 = pool.GetConnection(); pool.ReturnConnection(connection1); pool.ReturnConnection(connection2); // Act pool.Dispose(); // Assert connectionMock.Verify(x => x.Dispose(), Times.Exactly(2)); }
public void GetConnection_AfterReturnConnection_ShouldReturnSameConnection() { // Arrange var pool = new SapConnectionPool( ConnectionParameters, poolSize: 3, connectionFactory: _ => Mock.Of <ISapConnection>()); // Act ISapConnection connection1 = pool.GetConnection(); pool.ReturnConnection(connection1); ISapConnection connection2 = pool.GetConnection(); // Assert connection1.Should().NotBeNull(); connection2.Should().Be(connection1); }
/// <inheritdoc cref="ISapPooledConnection"/> public TOutput InvokeFunction <TOutput>(string name, CancellationToken cancellationToken = default) { try { _connection = _connection ?? _pool.GetConnection(cancellationToken); using (ISapFunction function = _connection.CreateFunction(name)) return(function.Invoke <TOutput>()); } catch (SapCommunicationFailedException) { // Let the pool collect the dead connection _pool.ForgetConnection(_connection); // Retry invocation with new connection from the pool _connection = _pool.GetConnection(cancellationToken); using (ISapFunction function = _connection.CreateFunction(name)) return(function.Invoke <TOutput>()); } }
/// <inheritdoc cref="ISapPooledConnection"/> public void InvokeFunction(string name, object input, CancellationToken cancellationToken = default) { try { _connection = _connection ?? _pool.GetConnection(cancellationToken); using (ISapFunction function = _connection.CreateFunction(name)) function.Invoke(input); } catch (SapCommunicationFailedException) { // Let the pool collect the dead connection _pool.ForgetConnection(_connection); // Retry invocation with new connection from the pool _connection = _pool.GetConnection(cancellationToken); using (ISapFunction function = _connection.CreateFunction(name)) function.Invoke(input); } }
public void GetConnection_ConnectionFactoryReturnsNullFirst_ShouldRetryUntilFactoryReturnsConnection() { // Arrange ISapConnection firstConnection = null; ISapConnection secondConnection = Mock.Of <ISapConnection>(); var connectionFactoryMock = new Mock <Func <SapConnectionParameters, ISapConnection> >(); connectionFactoryMock.SetupSequence(x => x(It.IsAny <SapConnectionParameters>())).Returns(firstConnection); connectionFactoryMock.SetupSequence(x => x(It.IsAny <SapConnectionParameters>())).Returns(secondConnection); var pool = new SapConnectionPool( ConnectionParameters, poolSize: 1, connectionFactory: connectionFactoryMock.Object); // Act ISapConnection connection = pool.GetConnection(); // Assert connection.Should().Be(secondConnection); }
public void ReturnConnection_ExceedPoolSize_GetConnectionShouldBlockAndReturnFirstReturnedConnection() { // Arrange var pool = new SapConnectionPool( ConnectionParameters, poolSize: 2, connectionFactory: _ => Mock.Of <ISapConnection>()); ISapConnection connection1 = pool.GetConnection(); ISapConnection connection2 = pool.GetConnection(); // Act Task.Run(async() => { await Task.Delay(150); pool.ReturnConnection(connection1); await Task.Delay(150); pool.ReturnConnection(connection2); }); var sw = new Stopwatch(); sw.Start(); ISapConnection connection3 = pool.GetConnection(); sw.Stop(); // Assert sw.ElapsedMilliseconds.Should().BeGreaterThan(100).And.BeLessThan(250); connection3.Should().NotBeNull(); connection3.Should().Be(connection1); connection1.Dispose(); connection2.Dispose(); connection3.Dispose(); pool.Dispose(); }