Skip to content

Commit 3d57d0f

Browse files
NH-2319 - Test case dedicated to plan cache previous bug, to be squashed
1 parent 4ec95de commit 3d57d0f

File tree

2 files changed

+101
-26
lines changed

2 files changed

+101
-26
lines changed

src/NHibernate.Test/Async/NHSpecificTest/NH2319/Fixture.cs

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,45 @@
1313
using NHibernate.Cfg;
1414
using NHibernate.Cfg.MappingSchema;
1515
using NHibernate.Collection;
16+
using NHibernate.Engine.Query;
1617
using NHibernate.Mapping.ByCode;
1718
using NUnit.Framework;
1819
using NHibernate.Linq;
1920

2021
namespace NHibernate.Test.NHSpecificTest.NH2319
2122
{
2223
using System.Threading.Tasks;
24+
using System.Threading;
2325
[TestFixture]
2426
public abstract class FixtureBaseAsync : TestCaseMappingByCode
2527
{
26-
private Guid _parentId;
28+
private Guid _parent1Id;
2729
private Guid _child1Id;
30+
private Guid _parent2Id;
31+
private Guid _child3Id;
2832

2933
[Test]
30-
public async Task ShouldBeAbleToFindChildrenByNameAsync()
34+
public Task ShouldBeAbleToFindChildrenByNameAsync()
35+
{
36+
return FindChildrenByNameAsync(_parent1Id, _child1Id);
37+
}
38+
39+
private async Task FindChildrenByNameAsync(Guid parentId, Guid childId, CancellationToken cancellationToken = default(CancellationToken))
3140
{
3241
using (var session = OpenSession())
3342
using (session.BeginTransaction())
3443
{
35-
var parent = await (session.GetAsync<Parent>(_parentId));
44+
var parent = await (session.GetAsync<Parent>(parentId, cancellationToken));
3645

3746
Assert.That(parent, Is.Not.Null);
3847

3948
var filtered = await (parent.Children
4049
.AsQueryable()
4150
.Where(x => x.Name == "Jack")
42-
.ToListAsync());
51+
.ToListAsync(cancellationToken));
4352

4453
Assert.That(filtered, Has.Count.EqualTo(1));
45-
Assert.That(filtered[0].Id, Is.EqualTo(_child1Id));
54+
Assert.That(filtered[0].Id, Is.EqualTo(childId));
4655
}
4756
}
4857

@@ -52,7 +61,7 @@ public async Task ShouldBeAbleToPerformComplexFilteringAsync()
5261
using (var session = OpenSession())
5362
using (session.BeginTransaction())
5463
{
55-
var parent = await (session.GetAsync<Parent>(_parentId));
64+
var parent = await (session.GetAsync<Parent>(_parent1Id));
5665

5766
Assert.NotNull(parent);
5867

@@ -67,13 +76,42 @@ public async Task ShouldBeAbleToPerformComplexFilteringAsync()
6776
}
6877
}
6978

79+
[Test]
80+
public async Task ShouldBeAbleToReuseQueryPlanAsync()
81+
{
82+
await (ShouldBeAbleToFindChildrenByNameAsync());
83+
using (var spy = new LogSpy(typeof(QueryPlanCache)))
84+
{
85+
Assert.That(ShouldBeAbleToFindChildrenByNameAsync, Throws.Nothing);
86+
AssertPlanCacheHit(spy);
87+
}
88+
}
89+
90+
[Test]
91+
public async Task ShouldNotMixResultsAsync()
92+
{
93+
await (FindChildrenByNameAsync(_parent1Id, _child1Id));
94+
using (var spy = new LogSpy(typeof(QueryPlanCache)))
95+
{
96+
await (FindChildrenByNameAsync(_parent2Id, _child3Id));
97+
AssertPlanCacheHit(spy);
98+
}
99+
}
100+
101+
private static void AssertPlanCacheHit(LogSpy spy) =>
102+
// Each query currently ask the cache two times, so asserting reuse requires to check cache has not been missed
103+
// rather than only asserting it has been hit.
104+
Assert.That(spy.GetWholeLog(),
105+
Contains.Substring("located collection-filter query plan in cache (")
106+
.And.Not.Contains("unable to locate collection-filter query plan in cache"));
107+
70108
[Test]
71109
public async Task ShouldNotInitializeCollectionWhenPerformingQueryAsync()
72110
{
73111
using (var session = OpenSession())
74112
using (session.BeginTransaction())
75113
{
76-
var parent = await (session.GetAsync<Parent>(_parentId));
114+
var parent = await (session.GetAsync<Parent>(_parent1Id));
77115
Assert.That(parent, Is.Not.Null);
78116

79117
var persistentCollection = (IPersistentCollection) parent.Children;
@@ -94,7 +132,7 @@ public async Task ShouldPerformSqlQueryEvenIfCollectionAlreadyInitializedAsync()
94132
using (var session = OpenSession())
95133
using (session.BeginTransaction())
96134
{
97-
var parent = await (session.GetAsync<Parent>(_parentId));
135+
var parent = await (session.GetAsync<Parent>(_parent1Id));
98136
Assert.That(parent, Is.Not.Null);
99137

100138
var loaded = parent.Children.ToList();
@@ -120,7 +158,7 @@ public async Task TestFilterAsync()
120158
using (var session = OpenSession())
121159
using (session.BeginTransaction())
122160
{
123-
var parent = await (session.GetAsync<Parent>(_parentId));
161+
var parent = await (session.GetAsync<Parent>(_parent1Id));
124162
Assert.That(parent, Is.Not.Null);
125163

126164
var children = await ((await (session.CreateFilterAsync(parent.Children, "where this.Name = 'Jack'")))
@@ -141,11 +179,11 @@ protected override void OnSetUp()
141179
using (var session = OpenSession())
142180
using (var transaction = session.BeginTransaction())
143181
{
144-
var parent1 = new Parent {Name = "Bob"};
145-
_parentId = (Guid) session.Save(parent1);
182+
var parent1 = new Parent { Name = "Bob" };
183+
_parent1Id = (Guid) session.Save(parent1);
146184

147-
var parent2 = new Parent {Name = "Martin"};
148-
session.Save(parent2);
185+
var parent2 = new Parent { Name = "Martin" };
186+
_parent2Id = (Guid) session.Save(parent2);
149187

150188
var child1 = new Child
151189
{
@@ -185,7 +223,7 @@ protected override void OnSetUp()
185223
Parent = parent2
186224
};
187225
parent2.Children.Add(child3);
188-
session.Save(child3);
226+
_child3Id = (Guid) session.Save(child3);
189227

190228
session.Flush();
191229
transaction.Commit();

src/NHibernate.Test/NHSpecificTest/NH2319/Fixture.cs

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using NHibernate.Cfg;
44
using NHibernate.Cfg.MappingSchema;
55
using NHibernate.Collection;
6+
using NHibernate.Engine.Query;
67
using NHibernate.Mapping.ByCode;
78
using NUnit.Framework;
89

@@ -11,16 +12,23 @@ namespace NHibernate.Test.NHSpecificTest.NH2319
1112
[TestFixture]
1213
public abstract class FixtureBase : TestCaseMappingByCode
1314
{
14-
private Guid _parentId;
15+
private Guid _parent1Id;
1516
private Guid _child1Id;
17+
private Guid _parent2Id;
18+
private Guid _child3Id;
1619

1720
[Test]
1821
public void ShouldBeAbleToFindChildrenByName()
22+
{
23+
FindChildrenByName(_parent1Id, _child1Id);
24+
}
25+
26+
private void FindChildrenByName(Guid parentId, Guid childId)
1927
{
2028
using (var session = OpenSession())
2129
using (session.BeginTransaction())
2230
{
23-
var parent = session.Get<Parent>(_parentId);
31+
var parent = session.Get<Parent>(parentId);
2432

2533
Assert.That(parent, Is.Not.Null);
2634

@@ -30,7 +38,7 @@ public void ShouldBeAbleToFindChildrenByName()
3038
.ToList();
3139

3240
Assert.That(filtered, Has.Count.EqualTo(1));
33-
Assert.That(filtered[0].Id, Is.EqualTo(_child1Id));
41+
Assert.That(filtered[0].Id, Is.EqualTo(childId));
3442
}
3543
}
3644

@@ -40,7 +48,7 @@ public void ShouldBeAbleToPerformComplexFiltering()
4048
using (var session = OpenSession())
4149
using (session.BeginTransaction())
4250
{
43-
var parent = session.Get<Parent>(_parentId);
51+
var parent = session.Get<Parent>(_parent1Id);
4452

4553
Assert.NotNull(parent);
4654

@@ -55,13 +63,42 @@ public void ShouldBeAbleToPerformComplexFiltering()
5563
}
5664
}
5765

66+
[Test]
67+
public void ShouldBeAbleToReuseQueryPlan()
68+
{
69+
ShouldBeAbleToFindChildrenByName();
70+
using (var spy = new LogSpy(typeof(QueryPlanCache)))
71+
{
72+
Assert.That(ShouldBeAbleToFindChildrenByName, Throws.Nothing);
73+
AssertPlanCacheHit(spy);
74+
}
75+
}
76+
77+
[Test]
78+
public void ShouldNotMixResults()
79+
{
80+
FindChildrenByName(_parent1Id, _child1Id);
81+
using (var spy = new LogSpy(typeof(QueryPlanCache)))
82+
{
83+
FindChildrenByName(_parent2Id, _child3Id);
84+
AssertPlanCacheHit(spy);
85+
}
86+
}
87+
88+
private static void AssertPlanCacheHit(LogSpy spy) =>
89+
// Each query currently ask the cache two times, so asserting reuse requires to check cache has not been missed
90+
// rather than only asserting it has been hit.
91+
Assert.That(spy.GetWholeLog(),
92+
Contains.Substring("located collection-filter query plan in cache (")
93+
.And.Not.Contains("unable to locate collection-filter query plan in cache"));
94+
5895
[Test]
5996
public void ShouldNotInitializeCollectionWhenPerformingQuery()
6097
{
6198
using (var session = OpenSession())
6299
using (session.BeginTransaction())
63100
{
64-
var parent = session.Get<Parent>(_parentId);
101+
var parent = session.Get<Parent>(_parent1Id);
65102
Assert.That(parent, Is.Not.Null);
66103

67104
var persistentCollection = (IPersistentCollection) parent.Children;
@@ -82,7 +119,7 @@ public void ShouldPerformSqlQueryEvenIfCollectionAlreadyInitialized()
82119
using (var session = OpenSession())
83120
using (session.BeginTransaction())
84121
{
85-
var parent = session.Get<Parent>(_parentId);
122+
var parent = session.Get<Parent>(_parent1Id);
86123
Assert.That(parent, Is.Not.Null);
87124

88125
var loaded = parent.Children.ToList();
@@ -108,7 +145,7 @@ public void TestFilter()
108145
using (var session = OpenSession())
109146
using (session.BeginTransaction())
110147
{
111-
var parent = session.Get<Parent>(_parentId);
148+
var parent = session.Get<Parent>(_parent1Id);
112149
Assert.That(parent, Is.Not.Null);
113150

114151
var children = session.CreateFilter(parent.Children, "where this.Name = 'Jack'")
@@ -129,11 +166,11 @@ protected override void OnSetUp()
129166
using (var session = OpenSession())
130167
using (var transaction = session.BeginTransaction())
131168
{
132-
var parent1 = new Parent {Name = "Bob"};
133-
_parentId = (Guid) session.Save(parent1);
169+
var parent1 = new Parent { Name = "Bob" };
170+
_parent1Id = (Guid) session.Save(parent1);
134171

135-
var parent2 = new Parent {Name = "Martin"};
136-
session.Save(parent2);
172+
var parent2 = new Parent { Name = "Martin" };
173+
_parent2Id = (Guid) session.Save(parent2);
137174

138175
var child1 = new Child
139176
{
@@ -173,7 +210,7 @@ protected override void OnSetUp()
173210
Parent = parent2
174211
};
175212
parent2.Children.Add(child3);
176-
session.Save(child3);
213+
_child3Id = (Guid) session.Save(child3);
177214

178215
session.Flush();
179216
transaction.Commit();

0 commit comments

Comments
 (0)