Improving cache concurrency unit tests

This commit is contained in:
Sebastien Ros 2017-04-03 12:46:50 -07:00
parent 22a7d6d44d
commit 4a6d8a6530

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using Autofac; using Autofac;
using NUnit.Framework; using NUnit.Framework;
using Orchard.Caching; using Orchard.Caching;
@ -84,33 +85,73 @@ namespace Orchard.Tests.Caching {
public void CacheManagerIsNotBlocking() { public void CacheManagerIsNotBlocking() {
var hits = 0; var hits = 0;
string result = ""; string result = "";
string key = "key";
Enumerable.Range(0, 5).AsParallel().ForAll(x => var e1 = new ManualResetEvent(false);
result = _cacheManager.Get("testItem", ctx => { var e2 = new ManualResetEvent(false);
// by waiting for 100ms we expect all the calls to Get var e3 = new ManualResetEvent(false);
// to enter this lambda
Thread.Sleep(100); // task1 is started first, when inside the lambda, we are waiting
// for the test to give the green light. Then we unblock the task2
var task1 = Task.Run(() => {
result = _cacheManager.Get(key, ctx => {
e1.WaitOne(TimeSpan.FromSeconds(5));
hits++; hits++;
e2.Set();
e3.WaitOne(TimeSpan.FromSeconds(5));
return "testResult"; return "testResult";
}) });
); });
// task2 is called once task1 is inside the lambda, ensuring it's not blocking.
var task2 = Task.Run(() => {
e2.WaitOne(TimeSpan.FromSeconds(5));
result = _cacheManager.Get(key, ctx => {
hits++;
e3.Set();
return "testResult";
});
});
e1.Set();
Task.WaitAll(task1, task2);
Assert.That(result, Is.EqualTo("testResult")); Assert.That(result, Is.EqualTo("testResult"));
Assert.That(hits, Is.GreaterThan(1)); Assert.That(hits, Is.EqualTo(2));
} }
[Test] [Test]
public void CacheManagerIsBlocking() { public void CacheManagerIsBlocking() {
var hits = 0; var hits = 0;
string result = ""; string result = "";
string key = "key";
Enumerable.Range(0, 5).AsParallel().ForAll(x => var e1 = new ManualResetEvent(false);
result = _cacheManager.Get("testItem", true, ctx => { var e2 = new ManualResetEvent(false);
Thread.Sleep(100);
// task1 is started first, when inside the lambda, we are waiting
// for the test to give the green light. Then we unblock the task2
var task1 = Task.Run(() => {
result = _cacheManager.Get(key, true, ctx => {
e1.WaitOne(TimeSpan.FromSeconds(5));
hits++;
e2.Set();
return "testResult";
});
});
// task2 is called once task1 is inside the lambda. Here we expect the lamda not to be called.
var task2 = Task.Run(() => {
e2.WaitOne(TimeSpan.FromSeconds(5));
result = _cacheManager.Get(key, true, ctx => {
hits++; hits++;
return "testResult"; return "testResult";
}) });
); });
e1.Set();
Task.WaitAll(task1, task2);
Assert.That(result, Is.EqualTo("testResult")); Assert.That(result, Is.EqualTo("testResult"));
Assert.That(hits, Is.EqualTo(1)); Assert.That(hits, Is.EqualTo(1));