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.Linq;
using System.Threading;
using System.Threading.Tasks;
using Autofac;
using NUnit.Framework;
using Orchard.Caching;
@ -84,33 +85,73 @@ namespace Orchard.Tests.Caching {
public void CacheManagerIsNotBlocking() {
var hits = 0;
string result = "";
string key = "key";
Enumerable.Range(0, 5).AsParallel().ForAll(x =>
result = _cacheManager.Get("testItem", ctx => {
// by waiting for 100ms we expect all the calls to Get
// to enter this lambda
Thread.Sleep(100);
var e1 = new ManualResetEvent(false);
var e2 = new ManualResetEvent(false);
var e3 = new ManualResetEvent(false);
// 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++;
e2.Set();
e3.WaitOne(TimeSpan.FromSeconds(5));
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(hits, Is.GreaterThan(1));
Assert.That(hits, Is.EqualTo(2));
}
[Test]
public void CacheManagerIsBlocking() {
var hits = 0;
string result = "";
string key = "key";
Enumerable.Range(0, 5).AsParallel().ForAll(x =>
result = _cacheManager.Get("testItem", true, ctx => {
Thread.Sleep(100);
var e1 = new ManualResetEvent(false);
var e2 = new ManualResetEvent(false);
// 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++;
return "testResult";
})
);
});
});
e1.Set();
Task.WaitAll(task1, task2);
Assert.That(result, Is.EqualTo("testResult"));
Assert.That(hits, Is.EqualTo(1));