-
Notifications
You must be signed in to change notification settings - Fork 247
Expand file tree
/
Copy pathOwnedConnectionStrategyTestCases.cs
More file actions
64 lines (55 loc) · 2.63 KB
/
OwnedConnectionStrategyTestCases.cs
File metadata and controls
64 lines (55 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using NUnit.Framework;
using System.Data.Common;
using System.Diagnostics;
namespace Medallion.Threading.Tests.Data;
public abstract class OwnedConnectionStrategyTestCases<TLockProvider, TDb>
where TLockProvider : TestingLockProvider<TestingOwnedConnectionSynchronizationStrategy<TDb>>, new()
where TDb : TestingPrimaryClientDb, new()
{
private TLockProvider _lockProvider = default!;
[SetUp]
public async Task SetUp()
{
this._lockProvider = new TLockProvider();
await this._lockProvider.SetupAsync();
}
[TearDown]
public async Task TearDown() => await this._lockProvider.DisposeAsync();
/// <summary>
/// Tests that our idle session killer works, therefore validating our other tests that use it.
///
/// We test this here rather than in <see cref="ConnectionStringStrategyTestCases{TLockProvider, TStrategy, TDb}"/>
/// because (a) we don't need to repeat the test for both regular and multiplexed and (2) for owned-transaction the test won't
/// pass because you can safely Dispose a transaction on a killed SQL connection
/// </summary>
[Test]
public void TestIdleSessionKiller()
{
// This makes sure that for the Semaphore5 lock initial 4 tickets are taken with the default
// application name and therefore won't be counted or killed
this._lockProvider.CreateLock(nameof(TestIdleSessionKiller));
var applicationName = this._lockProvider.Strategy.Db.SetUniqueApplicationName();
var @lock = this._lockProvider.CreateLock(nameof(TestIdleSessionKiller));
// go through one acquire/dispose cycle to ensure all commands are prepared. Due to
// https://github.com/npgsql/npgsql/issues/2912 in Postgres, we get NRE on the post-kill Dispose()
// call rather than the DbException we expected.
@lock.Acquire().Dispose();
using var handle = @lock.Acquire();
this._lockProvider.Strategy.Db.CountActiveSessions(applicationName).ShouldEqual(1);
using var idleSessionKiller = new IdleSessionKiller(this._lockProvider.Strategy.Db, applicationName, idleTimeout: TimeSpan.FromSeconds(.1));
var stopwatch = Stopwatch.StartNew();
while (true)
{
Thread.Sleep(TimeSpan.FromSeconds(.02));
if (this._lockProvider.Strategy.Db.CountActiveSessions(applicationName) == 0)
{
break;
}
if (stopwatch.Elapsed > TimeSpan.FromSeconds(5))
{
Assert.Fail("Timed out waiting for idle session to be killed");
}
}
Assert.Catch<DbException>(handle.Dispose);
}
}