private void FireReadingFromCache(ICache cache, UnitTestThreadCacheController unitTestController, object result) { new Thread(() => { try { unitTestController.result = cache.Get(unitTestController.cacheKey , TimeSpan.FromSeconds(unitTestController.expirySeconds), () => { unitTestController.startedPopulating = true; while (unitTestController.hold) { Thread.Sleep(10); } if (unitTestController.throwException) { throw new Exception("unit test"); } return(result); }); } catch (Exception) { unitTestController.exceptionThrown = true; } unitTestController.finished = true; }).Start(); }
public void Cache_IsNotBlockedIfAnotherKeyIsBeingRefreshed() { ICache cache = new InMemoryCache(); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; var resultFromThread1 = new object(); var thread2CacheController = new UnitTestThreadCacheController(); var resultFromThread2 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); FireReadingFromCache(cache, thread2CacheController, resultFromThread2); EnsureReadingFinished(thread2CacheController); Assert.Equal(resultFromThread2, thread2CacheController.result); Assert.False(thread1CacheController.finished); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); Assert.Equal(resultFromThread1, thread1CacheController.result); }
public void SecondReadStillReturnTheResultOfFirstDespiteCacheExpiredBecauseItWasLocked() { var LocksCollection = new TestLocksCollection <string, InMemoryCache.CachedObjectLock>(); ICache cache = new InMemoryCacheAllow0Expiry(LocksCollection); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; thread1CacheController.expirySeconds = 0; var resultFromThread1 = new object(); var thread2CacheController = new UnitTestThreadCacheController(); thread2CacheController.cacheKey = thread1CacheController.cacheKey; var resultFromThread2 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); FireReadingFromCache(cache, thread2CacheController, resultFromThread2); WaitUntilTwoThreadsPickedLockObjectsUp(LocksCollection); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); EnsureReadingFinished(thread2CacheController); Assert.Equal(resultFromThread1, thread1CacheController.result); Assert.Equal(resultFromThread1, thread2CacheController.result); }
public void IfExceptionThrown_LockedCallsShouldAlsoThrow_NotReturnNull() { var locksCollection = new TestLocksCollection <string, InMemoryCache.CachedObjectLock>(); ICache cache = new InMemoryCache(locksCollection); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; thread1CacheController.throwException = true; var resultFromThread1 = new object(); var thread2CacheController = new UnitTestThreadCacheController(); thread2CacheController.cacheKey = thread1CacheController.cacheKey; var resultFromThread2 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); FireReadingFromCache(cache, thread2CacheController, resultFromThread2); WaitUntilTwoThreadsPickedLockObjectsUp(locksCollection); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); Assert.True(thread1CacheController.exceptionThrown); EnsureReadingFinished(thread2CacheController); Assert.True(thread2CacheController.exceptionThrown); }
public void Cache_KeyShouldBeRemovedFromTheCollectionToAvoidMemoryLeak_TwoThreadsOnTheSameKey() { var locksCollection = new TestLocksCollection <string, InMemoryCache.CachedObjectLock>(); ICache cache = new InMemoryCache(locksCollection); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; var resultFromThread1 = new object(); var thread2CacheController = new UnitTestThreadCacheController(); thread2CacheController.cacheKey = thread1CacheController.cacheKey; var resultFromThread2 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); FireReadingFromCache(cache, thread2CacheController, resultFromThread2); WaitUntilTwoThreadsPickedLockObjectsUp(locksCollection); Assert.True(locksCollection.ContainsKey(thread1CacheController.cacheKey)); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); EnsureReadingFinished(thread2CacheController); Assert.False(locksCollection.ContainsKey(thread1CacheController.cacheKey)); Assert.False(thread1CacheController.exceptionThrown); Assert.False(thread2CacheController.exceptionThrown); }
public void Cache_IsBlockedIfTheSameKeyIsBeingRefreshed() { var locksCollection = new TestLocksCollection <string, InMemoryCache.CachedObjectLock>(); ICache cache = new InMemoryCache(locksCollection); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; var resultFromThread1 = new object(); var thread2CacheController = new UnitTestThreadCacheController(); thread2CacheController.cacheKey = thread1CacheController.cacheKey; var resultFromThread2 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); FireReadingFromCache(cache, thread2CacheController, resultFromThread2); WaitUntilTwoThreadsPickedLockObjectsUp(locksCollection); Assert.False(thread2CacheController.finished); Assert.False(thread1CacheController.finished); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); EnsureReadingFinished(thread2CacheController); Assert.Equal(resultFromThread1, thread1CacheController.result); Assert.Equal(resultFromThread1, thread2CacheController.result); }
public void Cache_KeyShouldBeRemovedFromTheCollectionToAvoidMemoryLeak() { ILocksCollection <string, InMemoryCache.CachedObjectLock> testLocksCollection = new TestLocksCollection <string, InMemoryCache.CachedObjectLock>(); ICache cache = new InMemoryCache(testLocksCollection); var thread1CacheController = new UnitTestThreadCacheController(); thread1CacheController.hold = true; var resultFromThread1 = new object(); FireReadingFromCache(cache, thread1CacheController, resultFromThread1); WaitUntilThreadStartsPopulating(thread1CacheController); Assert.True(testLocksCollection.ContainsKey(thread1CacheController.cacheKey)); thread1CacheController.hold = false; EnsureReadingFinished(thread1CacheController); Assert.False(testLocksCollection.ContainsKey(thread1CacheController.cacheKey)); }
private void WaitUntilThreadStartsPopulating(UnitTestThreadCacheController unitTestController) { WaitUntil(() => unitTestController.startedPopulating); }
private void EnsureReadingFinished(UnitTestThreadCacheController unitTestController) { WaitUntil(() => unitTestController.finished); }