Skip to content

Commit

Permalink
SNOW-902611
Browse files Browse the repository at this point in the history
- removed singleton pattern from SessionPool; introduced new interface for ConnectionManager; split tests of ConnectionPool and some cleanup in the classes
SNOW-902608
- new Connection Pool Manager version implementation
- unit tests for new pool; introduction of SessionFactory for unit testing of new pool manager and session pooling
- integration tests for two versions of Connection Pool
  • Loading branch information
sfc-gh-mhofman committed Oct 16, 2023
1 parent 127343f commit 5f370cb
Show file tree
Hide file tree
Showing 14 changed files with 1,545 additions and 838 deletions.
360 changes: 360 additions & 0 deletions Snowflake.Data.Tests/IntegrationTests/SFConnectionPoolAsyncIT.cs

Large diffs are not rendered by default.

567 changes: 567 additions & 0 deletions Snowflake.Data.Tests/IntegrationTests/SFConnectionPoolIT.cs

Large diffs are not rendered by default.

775 changes: 0 additions & 775 deletions Snowflake.Data.Tests/IntegrationTests/SFConnectionPoolT.cs

This file was deleted.

215 changes: 215 additions & 0 deletions Snowflake.Data.Tests/UnitTests/ConnectionPoolManagerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*
* Copyright (c) 2023 Snowflake Computing Inc. All rights reserved.
*/

using System;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
using Snowflake.Data.Core;
using Snowflake.Data.Core.Session;
using Moq;

namespace Snowflake.Data.Tests.UnitTests
{
[TestFixture, NonParallelizable]
class ConnectionPoolManagerTest
{
private readonly ConnectionPoolManager _connectionPoolManager = new ConnectionPoolManager();
private readonly string _connectionString1 = "database=D1;warehouse=W1;account=A1;user=U1;password=P1;role=R1;";
private readonly string _connectionString2 = "database=D2;warehouse=W2;account=A2;user=U2;password=P2;role=R2;";
private readonly SecureString _password = new SecureString();

[OneTimeSetUp]
public static void BeforeAllTests()
{
// SnowflakeDbConnectionPool.SwapVersion(); // TODO: swap when new version is the default
SessionPool.SessionFactory = new MockSessionFactory();
}

[OneTimeTearDown]
public void AfterAllTests()
{
SessionPool.SessionFactory = new SessionFactory();
}

[Test]
public void TestPoolManagerReturnsSessionPoolForGivenConnectionString()
{
// Act
var sessionPool = _connectionPoolManager.GetPool(_connectionString1, _password);

// Assert
Assert.AreEqual(_connectionString1, sessionPool.ConnectionString);
Assert.AreEqual(_password, sessionPool.Password);
}

[Test]
public void TestPoolManagerReturnsSamePoolForGivenConnectionString()
{
// Arrange
var anotherConnectionString = _connectionString1;

// Act
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);
var sessionPool2 = _connectionPoolManager.GetPool(anotherConnectionString, _password);

// Assert
Assert.AreEqual(sessionPool1, sessionPool2);
}

[Test]
public void TestDifferentPoolsAreReturnedForDifferentConnectionStrings()
{
// Arrange
Assert.AreNotSame(_connectionString1, _connectionString2);

// Act
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);
var sessionPool2 = _connectionPoolManager.GetPool(_connectionString2, _password);

// Assert
Assert.AreNotSame(sessionPool1, sessionPool2);
Assert.AreEqual(_connectionString1, sessionPool1.ConnectionString);
Assert.AreEqual(_connectionString2, sessionPool2.ConnectionString);
}


[Test]
public void TestGetSessionWorksForSpecifiedConnectionString()
{
// Act
var sfSession = _connectionPoolManager.GetSession(_connectionString1, _password);

// Assert
Assert.AreEqual(_connectionString1, sfSession.ConnectionString);
Assert.AreEqual(_password, sfSession.Password);
}

[Test]
public async Task TestGetSessionAsyncWorksForSpecifiedConnectionString()
{
// Act
var sfSession = await _connectionPoolManager.GetSessionAsync(_connectionString1, _password, CancellationToken.None);

// Assert
Assert.AreEqual(_connectionString1, sfSession.ConnectionString);
Assert.AreEqual(_password, sfSession.Password);
}

[Test]
[Ignore("Enable after completion of SNOW-937189")] // TODO:
public void TestCountingOfSessionProvidedByPool()
{
// Act
_connectionPoolManager.GetSession(_connectionString1, _password);

// Assert
var sessionPool = _connectionPoolManager.GetPool(_connectionString1, _password);
Assert.AreEqual(1, sessionPool.GetCurrentPoolSize());
}

[Test]
[Ignore("Enable after completion of SNOW-937189")] // TODO:
public void TestCountingOfSessionReturnedBackToPool()
{
// Arrange
var sfSession = _connectionPoolManager.GetSession(_connectionString1, _password);

// Act
_connectionPoolManager.AddSession(sfSession);

// Assert
var sessionPool = _connectionPoolManager.GetPool(_connectionString1, _password);
Assert.AreEqual(1, sessionPool.GetCurrentPoolSize());
}

[Test]
public void TestSetMaxPoolSizeForAllPools()
{
// Arrange
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);
var sessionPool2 = _connectionPoolManager.GetPool(_connectionString2, _password);

// Act
_connectionPoolManager.SetMaxPoolSize(3);

// Assert
Assert.AreEqual(3, sessionPool1.GetMaxPoolSize());
Assert.AreEqual(3, sessionPool2.GetMaxPoolSize());
}

[Test]
public void TestSetTimeoutForAllPools()
{
// Arrange
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);
var sessionPool2 = _connectionPoolManager.GetPool(_connectionString2, _password);

// Act
_connectionPoolManager.SetTimeout(3000);

// Assert
Assert.AreEqual(3000, sessionPool1.GetTimeout());
Assert.AreEqual(3000, sessionPool2.GetTimeout());
}

[Test]
public void TestSetPoolingDisabledForAllPools()
{
// Arrange
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);

// Act
_connectionPoolManager.SetPooling(false);

// Assert
Assert.AreEqual(false, sessionPool1.GetPooling());
}

[Test]
public void TestSetPoolingEnabledBack()
{
// Arrange
var sessionPool1 = _connectionPoolManager.GetPool(_connectionString1, _password);
_connectionPoolManager.SetPooling(false);

// Act
_connectionPoolManager.SetPooling(true);

// Assert
Assert.AreEqual(true, sessionPool1.GetPooling());
}

[Test]
public void TestGetPoolingOnManagerLevelNotSupported()
{
Assert.Throws<NotSupportedException>(() => _connectionPoolManager.GetPooling());
}

[Test]
public void TestGetTimeoutOnManagerLevelNotSupported()
{
Assert.Throws<NotSupportedException>(() => _connectionPoolManager.GetTimeout());
}

[Test]
public void TestGetMaxPoolSizeOnManagerLevelNotSupported()
{
Assert.Throws<NotSupportedException>(() => _connectionPoolManager.GetMaxPoolSize());
}
}

class MockSessionFactory : ISessionFactory
{
public SFSession NewSession(string connectionString, SecureString password)
{
var mockSfSession = new Mock<SFSession>(connectionString, password);
mockSfSession.Setup(x => x.Open()).Verifiable();
mockSfSession.Setup(x => x.OpenAsync(default)).Returns(Task.FromResult(this));
return mockSfSession.Object;
}
}

}
33 changes: 33 additions & 0 deletions Snowflake.Data.Tests/Util/PoolConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2012-2021 Snowflake Computing Inc. All rights reserved.
*/

using Snowflake.Data.Client;
using Snowflake.Data.Core.Session;

namespace Snowflake.Data.Tests.Util
{
class PoolConfig
{
private readonly bool _pooling;
private readonly long _timeout;
private readonly int _maxPoolSize;
private readonly ConnectionPoolType _connectionPoolType;

public PoolConfig()
{
_maxPoolSize = SnowflakeDbConnectionPool.GetMaxPoolSize();
_timeout = SnowflakeDbConnectionPool.GetTimeout();
_pooling = SnowflakeDbConnectionPool.GetPooling();
_connectionPoolType = SnowflakeDbConnectionPool.GetConnectionPoolVersion();
}

public void Reset()
{
SnowflakeDbConnectionPool.SetMaxPoolSize(_maxPoolSize);
SnowflakeDbConnectionPool.SetTimeout(_timeout);
SnowflakeDbConnectionPool.SetPooling(_pooling);
SnowflakeDbConnectionPool.SetConnectionPoolVersion(_connectionPoolType);
}
}
}
Loading

0 comments on commit 5f370cb

Please sign in to comment.