-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathGuidRaw16TypeHandlerTests.cs
More file actions
81 lines (68 loc) · 2.98 KB
/
GuidRaw16TypeHandlerTests.cs
File metadata and controls
81 lines (68 loc) · 2.98 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
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Reflection;
using Dapper.Oracle.TypeHandler;
using Dapper.Oracle.TypeMapping;
using FluentAssertions;
using Oracle.ManagedDataAccess.Client;
using Xunit;
namespace Tests.Dapper.Oracle.TypeHandlerTests
{
public class GuidRaw16TypeHandlerTests
{
[Fact]
public void ConvertTo()
{
Guid input = Guid.NewGuid();
var parameter = new OracleParameter();
var sut = new GuidRaw16TypeHandler();
sut.SetValue(parameter,input);
parameter.Value.Should().BeEquivalentTo(input.ToByteArray());
parameter.OracleDbType.Should().Be(OracleDbType.Raw);
}
[Fact]
public void ConvertFrom()
{
Guid input = Guid.NewGuid();
var sut = new GuidRaw16TypeHandler();
var result = sut.Parse(input.ToByteArray());
result.Should().Be(input);
}
/// <summary>
/// Verifies that TypeHandlerBase.OracleDbTypeProperty cache does not grow
/// unboundedly when SetValue is called multiple times with the same parameter type.
///
/// This test catches a bug in DictionaryKeyComparer.Equals where the condition
/// "if (x != null && y != null) return false" caused every cache lookup to fail,
/// resulting in unbounded cache growth and memory leaks.
/// </summary>
[Fact]
public void SetValue_ShouldReuseCache_WhenCalledMultipleTimes()
{
var sut = new GuidRaw16TypeHandler();
// Get the OracleDbTypeProperty cache via reflection
var baseType = typeof(GuidRaw16TypeHandler).BaseType;
var cacheField = baseType?.GetField("OracleDbTypeProperty",
BindingFlags.NonPublic | BindingFlags.Static);
cacheField.Should().NotBeNull("TypeHandlerBase should have OracleDbTypeProperty field");
var cache = cacheField.GetValue(null) as ICollection;
cache.Should().NotBeNull("OracleDbTypeProperty should be a collection");
// Record initial cache count
int initialCount = cache.Count;
// Call SetValue multiple times with the same parameter type
const int iterations = 100;
for (int i = 0; i < iterations; i++)
{
var parameter = new OracleParameter();
sut.SetValue(parameter, Guid.NewGuid());
}
// Cache should have grown by at most 1 entry (for the OracleParameter + "Raw" combination)
int finalCount = cache.Count;
int cacheGrowth = finalCount - initialCount;
cacheGrowth.Should().BeLessOrEqualTo(1,
$"cache should reuse entries for same parameter type, but grew by {cacheGrowth} entries after {iterations} calls. " +
"This indicates a bug in DictionaryKeyComparer.Equals causing cache entries to never match.");
}
}
}