Strengthen connection pooling and locking tests

This commit is contained in:
2026-02-27 19:04:37 +01:00
parent aedb97e879
commit d534311b9a
2 changed files with 169 additions and 1 deletions

View File

@@ -80,6 +80,26 @@ namespace DynamORM.Tests.Helpers
Assert.GreaterOrEqual(_state.DisposeCalls, 1);
}
[Test]
public void TestConnectionPoolingTrimsIdleConnectionsAbovePreferredLimit()
{
CreateDatabase(DynamicDatabaseOptions.ConnectionPooling);
_db.ConnectionPoolingKeepOpenCount = 1;
_db.ConnectionPoolingMaximumOpenCount = 3;
var c1 = _db.Open();
var c2 = _db.Open();
var c3 = _db.Open();
c1.Dispose();
c2.Dispose();
c3.Dispose();
Assert.AreEqual(3, _state.CreatedConnections);
Assert.AreEqual(2, _state.CloseCalls);
Assert.AreEqual(2, _state.DisposeCalls);
}
[Test]
public void TestDirectTransactionUsesSameThreadConnectionAndSeparateThreadGetsDifferentOne()
{
@@ -112,6 +132,29 @@ namespace DynamORM.Tests.Helpers
}
}
[Test]
public void TestDirectTransactionUsesTransactionOnlyOnOwningThread()
{
CreateDatabase(DynamicDatabaseOptions.ConnectionPooling);
using (var transaction = _db.BeginTransaction())
{
ExecuteFakeCommand();
var otherThread = Task.Run(() => ExecuteFakeCommand());
Assert.IsTrue(otherThread.Wait(TimeSpan.FromSeconds(2)));
transaction.Commit();
}
lock (_state.SeenTransactions)
{
Assert.AreEqual(2, _state.SeenTransactions.Count);
Assert.NotNull(_state.SeenTransactions[0]);
Assert.IsNull(_state.SeenTransactions[1]);
}
}
[TestCase(DynamicDatabaseOptions.SingleConnection)]
[TestCase(DynamicDatabaseOptions.SingleTransaction)]
public void TestSingleModesSerializeCommandExecution(DynamicDatabaseOptions option)
@@ -134,6 +177,44 @@ namespace DynamORM.Tests.Helpers
Assert.AreEqual(1, _state.MaxConcurrentExecutions);
}
[TestCase(DynamicDatabaseOptions.SingleConnection)]
[TestCase(DynamicDatabaseOptions.SingleTransaction)]
public void TestSingleModesSerializeReaderLifetime(DynamicDatabaseOptions option)
{
CreateDatabase(option);
_state.BlockFirstReader = true;
_state.AllowReader.Reset();
IDataReader reader = null;
var task1 = Task.Run(() =>
{
using (var connection = _db.Open())
using (var command = connection.CreateCommand())
{
command.SetCommand("SELECT 1;");
reader = command.ExecuteReader();
}
});
Assert.IsTrue(_state.FirstReaderEntered.Wait(TimeSpan.FromSeconds(2)));
var secondCompleted = new ManualResetEventSlim(false);
var task2 = Task.Run(() =>
{
ExecuteFakeCommand();
secondCompleted.Set();
});
Assert.IsFalse(secondCompleted.Wait(TimeSpan.FromMilliseconds(200)));
_state.AllowReader.Set();
SpinWait.SpinUntil(() => reader != null, TimeSpan.FromSeconds(2));
reader.Dispose();
Assert.IsTrue(Task.WaitAll(new[] { task1, task2 }, TimeSpan.FromSeconds(5)));
Assert.AreEqual(1, _state.MaxConcurrentExecutions);
}
private void ExecuteFakeCommand()
{
using (var connection = _db.Open())