Skip to content

Commit 88411b7

Browse files
committed
Add GetMany for ReadWriteCache tests
1 parent c9ab94d commit 88411b7

File tree

2 files changed

+690
-0
lines changed

2 files changed

+690
-0
lines changed

src/NHibernate.Test/Async/CacheTest/BatchableCacheFixture.cs

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,351 @@ public async Task MultipleGetReadOnlyCollectionTestAsync()
213213
}
214214
}
215215

216+
[Test]
217+
public async Task GetManyReadWriteTestAsync()
218+
{
219+
var persister = Sfi.GetEntityPersister(typeof(ReadWrite).FullName);
220+
Assert.That(persister.Cache.Cache, Is.Not.Null);
221+
Assert.That(persister.Cache.Cache, Is.TypeOf<BatchableCache>());
222+
int[] getIds;
223+
int[] loadIds;
224+
225+
using (var s = Sfi.OpenSession())
226+
using (var tx = s.BeginTransaction())
227+
{
228+
var items = await (s.Query<ReadWrite>().ToListAsync());
229+
loadIds = getIds = items.OrderBy(o => o.Id).Select(o => o.Id).ToArray();
230+
await (tx.CommitAsync());
231+
}
232+
233+
// Batch size 3
234+
var parentTestCases = new List<Tuple<int[], int, int[][], int[], Func<int, bool>>>
235+
{
236+
// When the cache is empty, GetMany will be called three times. First time in type
237+
// DefaultLoadEventListener, the second time in BatchingEntityLoader and third in ReadWriteCache.
238+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
239+
loadIds,
240+
0,
241+
new[]
242+
{
243+
new[] {0, 1, 2}, // Triggered by LoadFromSecondLevelCache method of DefaultLoadEventListener type
244+
new[] {1, 2, 3}, // Triggered by Load method of BatchingEntityLoader type
245+
new[] {0, 1, 2} // Triggered by PutMany method of ReadWriteCache type
246+
},
247+
new[] {0, 1, 2},
248+
null
249+
),
250+
// When there are not enough uninitialized entities after the demanded one to fill the batch,
251+
// the nearest before the demanded entity are added.
252+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
253+
loadIds,
254+
4,
255+
new[]
256+
{
257+
new[] {4, 5, 3},
258+
new[] {5, 3, 2},
259+
new[] {4, 5, 3},
260+
},
261+
new[] {3, 4, 5},
262+
null
263+
),
264+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
265+
loadIds,
266+
5,
267+
new[]
268+
{
269+
new[] {5, 4, 3},
270+
new[] {4, 3, 2},
271+
new[] {5, 4, 3},
272+
},
273+
new[] {3, 4, 5},
274+
null
275+
),
276+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
277+
loadIds,
278+
0,
279+
new[]
280+
{
281+
new[] {0, 1, 2} // 0 get assembled and no further processing is done
282+
},
283+
null,
284+
(i) => i % 2 == 0 // Cache all even indexes before loading
285+
),
286+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
287+
loadIds,
288+
1,
289+
new[]
290+
{
291+
new[] {1, 2, 3}, // 2 gets assembled inside LoadFromSecondLevelCache
292+
new[] {3, 4, 5},
293+
new[] {1, 3, 5}
294+
},
295+
new[] {1, 3, 5},
296+
(i) => i % 2 == 0
297+
),
298+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
299+
loadIds,
300+
5,
301+
new[]
302+
{
303+
new[] {5, 4, 3}, // 4 gets assembled inside LoadFromSecondLevelCache
304+
new[] {3, 2, 1},
305+
new[] {1, 3, 5}
306+
},
307+
new[] {1, 3, 5},
308+
(i) => i % 2 == 0
309+
),
310+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
311+
loadIds,
312+
0,
313+
new[]
314+
{
315+
new[] {0, 1, 2}, // 1 gets assembled inside LoadFromSecondLevelCache
316+
new[] {2, 3, 4},
317+
new[] {0, 2, 4}
318+
},
319+
new[] {0, 2, 4},
320+
(i) => i % 2 != 0
321+
),
322+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
323+
loadIds,
324+
4,
325+
new[]
326+
{
327+
new[] {4, 5, 3}, // 5 and 3 get assembled inside LoadFromSecondLevelCache
328+
new[] {2, 1, 0},
329+
new[] {0, 2, 4}
330+
},
331+
new[] {0, 2, 4},
332+
(i) => i % 2 != 0
333+
),
334+
// Tests by loading different ids
335+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
336+
loadIds.Where((v, i) => i != 0).ToArray(),
337+
0,
338+
new[]
339+
{
340+
new[] {0, 5, 4}, // Triggered by LoadFromSecondLevelCache method of DefaultLoadEventListener type
341+
new[] {3, 4, 5}, // Triggered by Load method of BatchingEntityLoader type
342+
new[] {0, 4, 5}, // Triggered by PutMany method of ReadWriteCache type
343+
},
344+
new[] {0, 4, 5},
345+
null
346+
),
347+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
348+
loadIds.Where((v, i) => i != 4).ToArray(),
349+
4,
350+
new[]
351+
{
352+
new[] {4, 5, 3},
353+
new[] {5, 3, 2},
354+
new[] {3, 4, 5}
355+
},
356+
new[] {3, 4, 5},
357+
null
358+
),
359+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
360+
loadIds.Where((v, i) => i != 0).ToArray(),
361+
0,
362+
new[]
363+
{
364+
new[] {0, 5, 4} // 0 get assembled and no further processing is done
365+
},
366+
null,
367+
(i) => i % 2 == 0 // Cache all even indexes before loading
368+
),
369+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
370+
loadIds.Where((v, i) => i != 1).ToArray(),
371+
1,
372+
new[]
373+
{
374+
new[] {1, 5, 4}, // 4 gets assembled inside LoadFromSecondLevelCache
375+
new[] {5, 3, 2},
376+
new[] {1, 3, 5}
377+
},
378+
new[] {1, 3, 5},
379+
(i) => i % 2 == 0
380+
)
381+
};
382+
383+
foreach (var tuple in parentTestCases)
384+
{
385+
await (AssertMultipleCacheCallsAsync<ReadWrite>(tuple.Item1, getIds, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5));
386+
}
387+
}
388+
389+
[Test]
390+
public async Task GetManyReadWriteItemTestAsync()
391+
{
392+
var persister = Sfi.GetEntityPersister(typeof(ReadWriteItem).FullName);
393+
Assert.That(persister.Cache.Cache, Is.Not.Null);
394+
Assert.That(persister.Cache.Cache, Is.TypeOf<BatchableCache>());
395+
int[] getIds;
396+
int[] loadIds;
397+
398+
using (var s = Sfi.OpenSession())
399+
using (var tx = s.BeginTransaction())
400+
{
401+
var items = await (s.Query<ReadWriteItem>().Take(6).ToListAsync());
402+
loadIds = getIds = items.OrderBy(o => o.Id).Select(o => o.Id).ToArray();
403+
await (tx.CommitAsync());
404+
}
405+
// Batch size 4
406+
var parentTestCases = new List<Tuple<int[], int, int[][], int[], Func<int, bool>>>
407+
{
408+
// When the cache is empty, GetMany will be called three times. First time in type
409+
// DefaultLoadEventListener, the second time in BatchingEntityLoader and third in ReadWriteCache.
410+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
411+
loadIds,
412+
0,
413+
new[]
414+
{
415+
new[] {0, 1, 2, 3}, // Triggered by LoadFromSecondLevelCache method of DefaultLoadEventListener type
416+
new[] {1, 2, 3, 4}, // Triggered by Load method of BatchingEntityLoader type
417+
new[] {0, 1, 2, 3} // Triggered by PutMany method of ReadWriteCache type
418+
},
419+
new[] {0, 1, 2, 3},
420+
null
421+
),
422+
// When there are not enough uninitialized entities after the demanded one to fill the batch,
423+
// the nearest before the demanded entity are added.
424+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
425+
loadIds,
426+
4,
427+
new[]
428+
{
429+
new[] {4, 5, 3, 2},
430+
new[] {5, 3, 2, 1},
431+
new[] {4, 5, 3, 2}
432+
},
433+
new[] {2, 3, 4, 5},
434+
null
435+
),
436+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
437+
loadIds,
438+
5,
439+
new[]
440+
{
441+
new[] {5, 4, 3, 2},
442+
new[] {4, 3, 2, 1},
443+
new[] {5, 4, 3, 2}
444+
},
445+
new[] {2, 3, 4, 5},
446+
null
447+
),
448+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
449+
loadIds,
450+
0,
451+
new[]
452+
{
453+
new[] {0, 1, 2, 3} // 0 get assembled and no further processing is done
454+
},
455+
null,
456+
(i) => i % 2 == 0 // Cache all even indexes before loading
457+
),
458+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
459+
loadIds,
460+
1,
461+
new[]
462+
{
463+
new[] {1, 2, 3, 4}, // 2 and 4 get assembled inside LoadFromSecondLevelCache
464+
new[] {3, 5, 0},
465+
new[] {1, 3, 5}
466+
},
467+
new[] {1, 3, 5},
468+
(i) => i % 2 == 0
469+
),
470+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
471+
loadIds,
472+
5,
473+
new[]
474+
{
475+
new[] {5, 4, 3, 2}, // 4 and 2 get assembled inside LoadFromSecondLevelCache
476+
new[] {3, 1, 0},
477+
new[] {1, 3, 5}
478+
},
479+
new[] {1, 3, 5},
480+
(i) => i % 2 == 0
481+
),
482+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
483+
loadIds,
484+
0,
485+
new[]
486+
{
487+
new[] {0, 1, 2, 3}, // 1 and 3 get assembled inside LoadFromSecondLevelCache
488+
new[] {2, 4, 5},
489+
new[] {0, 2, 4}
490+
},
491+
new[] {0, 2, 4},
492+
(i) => i % 2 != 0
493+
),
494+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
495+
loadIds,
496+
4,
497+
new[]
498+
{
499+
new[] {4, 5, 3, 2}, // 5 and 3 get assembled inside LoadFromSecondLevelCache
500+
new[] {2, 1, 0},
501+
new[] {0, 2, 4}
502+
},
503+
new[] {0, 2, 4},
504+
(i) => i % 2 != 0
505+
),
506+
// Tests by loading different ids
507+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
508+
loadIds.Where((v, i) => i != 0).ToArray(),
509+
0,
510+
new[]
511+
{
512+
new[] {0, 5, 4, 3}, // Triggered by LoadFromSecondLevelCache method of DefaultLoadEventListener type
513+
new[] {5, 4, 3, 2}, // Triggered by Load method of BatchingEntityLoader type
514+
new[] {0, 5, 4, 3}, // Triggered by PutMany method of ReadWriteCache type
515+
},
516+
new[] {0, 5, 4, 3},
517+
null
518+
),
519+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
520+
loadIds.Where((v, i) => i != 5).ToArray(),
521+
5,
522+
new[]
523+
{
524+
new[] {5, 4, 3, 2},
525+
new[] {4, 3, 2, 1},
526+
new[] {2, 3, 4, 5}
527+
},
528+
new[] {2, 3, 4, 5},
529+
null
530+
),
531+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
532+
loadIds.Where((v, i) => i != 0).ToArray(),
533+
0,
534+
new[]
535+
{
536+
new[] {0, 5, 4, 3} // 0 get assembled and no further processing is done
537+
},
538+
null,
539+
(i) => i % 2 == 0 // Cache all even indexes before loading
540+
),
541+
new Tuple<int[], int, int[][], int[], Func<int, bool>>(
542+
loadIds.Where((v, i) => i != 1).ToArray(),
543+
1,
544+
new[]
545+
{
546+
new[] {1, 5, 4, 3}, // 4 get assembled inside LoadFromSecondLevelCache
547+
new[] {5, 3, 2, 0},
548+
new[] {1, 3, 5}
549+
},
550+
new[] {1, 3, 5},
551+
(i) => i % 2 == 0
552+
),
553+
};
554+
555+
foreach (var tuple in parentTestCases)
556+
{
557+
await (AssertMultipleCacheCallsAsync<ReadWriteItem>(tuple.Item1, getIds, tuple.Item2, tuple.Item3, tuple.Item4, tuple.Item5));
558+
}
559+
}
560+
216561
[Test]
217562
public async Task MultipleGetReadOnlyTestAsync()
218563
{

0 commit comments

Comments
 (0)