-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSharedDisposableTests.cs
More file actions
109 lines (91 loc) · 3.51 KB
/
Copy pathSharedDisposableTests.cs
File metadata and controls
109 lines (91 loc) · 3.51 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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
namespace Kampute.HttpClient.Test.Utilities
{
using Kampute.HttpClient.Utilities;
using NUnit.Framework;
using System;
using System.Threading;
[TestFixture]
public class SharedDisposableTests
{
private class TestDisposable : IDisposable
{
public bool IsDisposed { get; private set; } = false;
public void Dispose() => IsDisposed = true;
}
[Test]
public void SharedDisposable_DefaultConstructor_CreatesResource_OnFirstReference()
{
var sharedDisposable = new SharedDisposable<TestDisposable>();
using var reference1 = sharedDisposable.AcquireReference();
Assert.Multiple(() =>
{
Assert.That(sharedDisposable.ReferenceCount, Is.EqualTo(1));
Assert.That(reference1.Instance, Is.Not.Null);
});
}
[Test]
public void SharedDisposable_FactoryConstructor_CreatesResource_OnFirstReference()
{
var factoryInvoked = 0;
var sharedDisposable = new SharedDisposable<TestDisposable>(() =>
{
++factoryInvoked;
return new TestDisposable();
});
using var reference1 = sharedDisposable.AcquireReference();
using var reference2 = sharedDisposable.AcquireReference();
Assert.Multiple(() =>
{
Assert.That(sharedDisposable.ReferenceCount, Is.EqualTo(2));
Assert.That(factoryInvoked, Is.EqualTo(1));
});
}
[Test]
public void SharedDisposable_DisposesResource_OnLastRelease()
{
var instance = new TestDisposable();
var sharedDisposable = new SharedDisposable<TestDisposable>(() => instance);
var reference1 = sharedDisposable.AcquireReference();
var reference2 = sharedDisposable.AcquireReference();
Assert.That(sharedDisposable.ReferenceCount, Is.EqualTo(2));
reference1.Dispose();
Assert.Multiple(() =>
{
Assert.That(sharedDisposable.ReferenceCount, Is.EqualTo(1));
Assert.That(instance.IsDisposed, Is.False);
});
reference2.Dispose();
Assert.Multiple(() =>
{
Assert.That(sharedDisposable.ReferenceCount, Is.EqualTo(0));
Assert.That(instance.IsDisposed, Is.True);
});
}
[Test]
public void SharedDisposable_MaintainsCorrectReferenceCount_OnConcurrentAcquireAndDispose()
{
var numberOfThreads = 100;
var threads = new Thread[numberOfThreads];
var createdCount = 0;
var sharedDisposable = new SharedDisposable<TestDisposable>(() => new TestDisposable());
for (var i = 0; i < numberOfThreads; i++)
{
threads[i] = new Thread(() =>
{
using var reference = sharedDisposable.AcquireReference();
Interlocked.Increment(ref createdCount);
Thread.Sleep(10);
});
}
foreach (var thread in threads)
thread.Start();
foreach (var thread in threads)
thread.Join();
Assert.Multiple(() =>
{
Assert.That(sharedDisposable.ReferenceCount, Is.Zero);
Assert.That(createdCount, Is.EqualTo(numberOfThreads));
});
}
}
}