Esempio n. 1
0
        public async Task TestCacheMiss()
        {
            ICacheKey    cacheKey = new SimpleCacheKey("http://hello.uri");
            EncodedImage image    = await _bufferedDiskCache.Get(cacheKey, _isCancelled);

            Assert.IsNull(image);
        }
Esempio n. 2
0
        public void TestConcurrency()
        {
            IList <Task> tasks = new List <Task>();

            using (Barrier barrier = new Barrier(3))
            {
                WriterCallbackImpl writerCallback = new WriterCallbackImpl((os) =>
                {
                    try
                    {
                        // Both threads will need to hit this barrier. If writing is serialized,
                        // the second thread will never reach here as the first will hold
                        // the write lock forever.
                        barrier.SignalAndWait();
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                });

                ICacheKey key1 = new SimpleCacheKey("concurrent1");
                ICacheKey key2 = new SimpleCacheKey("concurrent2");
                Task      t1   = RunInsertionInSeparateThread(key1, writerCallback);
                tasks.Add(t1);
                Task t2 = RunInsertionInSeparateThread(key2, writerCallback);
                tasks.Add(t2);
                barrier.SignalAndWait();
            }

            Task.WaitAll(tasks.ToArray());
        }
Esempio n. 3
0
        public void TestDoesntHaveKey()
        {
            ICacheKey key = new SimpleCacheKey("foo");

            Assert.IsFalse(_cache.HasKeySync(key));
            Assert.IsFalse(_cache.HasKey(key));
        }
Esempio n. 4
0
        public void TestWithMultiCacheKeys()
        {
            ICacheKey insertKey1 = new SimpleCacheKey("foo");

            byte[] value1 = new byte[101];
            value1[50] = 97; // 'a', just so it's not all zeros for the equality test below.
            _cache.Insert(insertKey1, WriterCallbacks.From(value1));

            List <ICacheKey> keys1 = new List <ICacheKey>(2);

            keys1.Add(new SimpleCacheKey("bar"));
            keys1.Add(new SimpleCacheKey("foo"));
            MultiCacheKey matchingMultiKey = new MultiCacheKey(keys1);

            CollectionAssert.AreEqual(value1, GetContents(_cache.GetResource(matchingMultiKey)));

            List <ICacheKey> keys2 = new List <ICacheKey>(2);

            keys2.Add(new SimpleCacheKey("one"));
            keys2.Add(new SimpleCacheKey("two"));
            MultiCacheKey insertKey2 = new MultiCacheKey(keys2);

            byte[] value2 = new byte[101];
            value1[50] = 98; // 'b', just so it's not all zeros for the equality test below.
            _cache.Insert(insertKey2, WriterCallbacks.From(value2));

            ICacheKey matchingSimpleKey = new SimpleCacheKey("one");

            CollectionAssert.AreEqual(value2, GetContents(_cache.GetResource(matchingSimpleKey)));
        }
Esempio n. 5
0
        public void TestVersioning()
        {
            // Define data that will be written to cache
            ICacheKey key = new SimpleCacheKey("version_test");

            byte[] value = new byte[32];
            value[0] = 118; // 'v'

            // Set up cache with version == 1
            IDiskStorage     storage1 = CreateDiskStorage(TESTCACHE_CURRENT_VERSION);
            DiskStorageCache cache1   = CreateDiskCache(storage1, false);

            // Write test data to cache 1
            cache1.Insert(key, WriterCallbacks.From(value));

            // Get cached file
            IBinaryResource resource1 = GetResource(storage1, key);

            Assert.IsNotNull(resource1);

            // Set up cache with version == 2
            IDiskStorage     storageSupplier2 = CreateDiskStorage(TESTCACHE_NEXT_VERSION);
            DiskStorageCache cache2           = CreateDiskCache(storageSupplier2, false);

            // Write test data to cache 2
            cache2.Insert(key, WriterCallbacks.From(value));

            // Get cached file
            IBinaryResource resource2 = GetResource(storageSupplier2, key);

            Assert.IsNotNull(resource2);

            // Make sure filenames of the two file are different
            Assert.IsFalse(resource2.Equals(resource1));
        }
Esempio n. 6
0
        private ICacheKey PutOneThingInCache()
        {
            ICacheKey key = new SimpleCacheKey("foo");

            byte[] value1 = new byte[101];
            value1[80] = 99; // 'c'
            _cache.Insert(key, WriterCallbacks.From(value1));
            return(key);
        }
Esempio n. 7
0
        public void TestCacheFileWithIOException()
        {
            ICacheKey key1 = new SimpleCacheKey("aaa");

            // Before inserting, make sure files not exist.
            IBinaryResource resource1 = GetResource(key1);

            Assert.IsNull(resource1);

            // 1. Should not create cache files if IOException happens in the middle.
            IOException writeException = new IOException();

            try
            {
                _cache.Insert(key1, new WriterCallbackImpl(os =>
                {
                    throw writeException;
                }));

                Assert.Fail();
            }
            catch (IOException)
            {
                Assert.IsNull(GetResource(key1));
            }

            VerifyListenerOnWriteAttempt(key1);
            VerifyListenerOnWriteException(key1, writeException);

            // 2. Test a read failure from DiskStorage
            ICacheKey key2       = new SimpleCacheKey("bbb");
            int       value2Size = 42;

            byte[] value2 = new byte[value2Size];
            value2[25] = 98; // 'b'
            _cache.Insert(key2, WriterCallbacks.From(value2));

            VerifyListenerOnWriteAttempt(key2);
            string resourceId2 = VerifyListenerOnWriteSuccessAndGetResourceId(key2, value2Size);

            ((DiskStorageWithReadFailures)_storage).SetPoisonResourceId(resourceId2);

            Assert.IsNull(_cache.GetResource(key2));
            VerifyListenerOnReadException(key2, new IOException("Poisoned resource requested"));

            Assert.IsFalse(_cache.Probe(key2));
            VerifyListenerOnReadException(key2, new IOException("Poisoned resource requested"));

            DuplicatingCacheEventListener listener = (DuplicatingCacheEventListener)_cacheEventListener;

            Assert.IsTrue(listener.GetEvents("OnCleared").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnHit").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnMiss").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnEviction").Count == 0);
        }
Esempio n. 8
0
        public void TestCleanOldCache()
        {
            TimeSpan  cacheExpiration = TimeSpan.FromDays(5);
            ICacheKey key1            = new SimpleCacheKey("aaa");
            int       value1Size      = 41;

            byte[] value1 = new byte[value1Size];
            value1[25] = 97; // 'a'
            _cache.Insert(key1, WriterCallbacks.From(value1));

            string resourceId1 = VerifyListenerOnWriteSuccessAndGetResourceId(key1, value1Size);

            ICacheKey key2       = new SimpleCacheKey("bbb");
            int       value2Size = 42;

            byte[] value2 = new byte[value2Size];
            value2[25] = 98; // 'b'
            _cache.Insert(key2, WriterCallbacks.From(value2));

            string resourceId2 = VerifyListenerOnWriteSuccessAndGetResourceId(key2, value2Size);

            // Increment clock by default expiration time + 1 day
            _clock.SetDateTime(DateTime.Now.Add(cacheExpiration + TimeSpan.FromDays(1)));

            ICacheKey key3       = new SimpleCacheKey("ccc");
            int       value3Size = 43;

            byte[] value3 = new byte[value3Size];
            value3[25] = 99; // 'c'
            _cache.Insert(key3, WriterCallbacks.From(value3));
            TimeSpan valueAge3 = TimeSpan.FromHours(1);

            _clock.SetDateTime(DateTime.Now.Add(cacheExpiration + TimeSpan.FromDays(1) + valueAge3));

            long oldestEntry = _cache.ClearOldEntries((long)cacheExpiration.TotalMilliseconds);

            Assert.IsTrue(valueAge3.TotalSeconds == oldestEntry / 1000);

            CollectionAssert.AreEqual(value3, GetContents(GetResource(key3)));
            Assert.IsNull(GetResource(key1));
            Assert.IsNull(GetResource(key2));

            string[] resourceIds             = new string[] { resourceId1, resourceId2 };
            long[]   itemSizes               = new long[] { value1Size, value2Size };
            long     cacheSizeBeforeEviction = value1Size + value2Size + value3Size;

            VerifyListenerOnEviction(
                resourceIds,
                itemSizes,
                EvictionReason.CONTENT_STALE,
                cacheSizeBeforeEviction);
        }
Esempio n. 9
0
        public void TestCacheEventListener()
        {
            // 1. Add first cache file
            ICacheKey key1       = new SimpleCacheKey("foo");
            int       value1Size = 101;

            byte[] value1 = new byte[value1Size];
            value1[80] = 99; // 'c', just so it's not all zeros for the equality test below.
            IBinaryResource resource1 = _cache.Insert(key1, WriterCallbacks.From(value1));

            VerifyListenerOnWriteAttempt(key1);
            string resourceId1 = VerifyListenerOnWriteSuccessAndGetResourceId(key1, value1Size);

            IBinaryResource resource1Again = _cache.GetResource(key1);

            Assert.AreEqual(((FileBinaryResource)resource1).File.FullName,
                            ((FileBinaryResource)resource1Again).File.FullName);
            VerifyListenerOnHit(key1, resourceId1);

            IBinaryResource resource1Again2 = _cache.GetResource(key1);

            Assert.AreEqual(((FileBinaryResource)resource1).File.FullName,
                            ((FileBinaryResource)resource1Again2).File.FullName);
            VerifyListenerOnHit(key1, resourceId1);

            SimpleCacheKey  missingKey = new SimpleCacheKey("nonexistent_key");
            IBinaryResource res2       = _cache.GetResource(missingKey);

            Assert.IsNull(res2);
            VerifyListenerOnMiss(missingKey);

            DuplicatingCacheEventListener listener = (DuplicatingCacheEventListener)_cacheEventListener;

            listener.Clear();
            _cache.ClearAll();
            Assert.IsTrue(listener.GetEvents("OnCleared").Count != 0);
            Assert.IsTrue(listener.GetEvents("OnHit").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnMiss").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnWriteAttempt").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnWriteSuccess").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnReadException").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnWriteException").Count == 0);
            Assert.IsTrue(listener.GetEvents("OnEviction").Count == 0);
        }
Esempio n. 10
0
        public void TestCleanOldCacheNoEntriesRemaining()
        {
            TimeSpan  cacheExpiration = TimeSpan.FromDays(5);
            ICacheKey key1            = new SimpleCacheKey("aaa");

            byte[] value1 = new byte[41];
            _cache.Insert(key1, WriterCallbacks.From(value1));

            ICacheKey key2 = new SimpleCacheKey("bbb");

            byte[] value2 = new byte[42];
            _cache.Insert(key2, WriterCallbacks.From(value2));

            // Increment clock by default expiration time + 1 day
            _clock.SetDateTime(DateTime.Now.Add(cacheExpiration + TimeSpan.FromDays(1)));

            long oldestEntry = _cache.ClearOldEntries((long)cacheExpiration.TotalMilliseconds);

            Assert.IsTrue(0 == oldestEntry);
        }
Esempio n. 11
0
        public void TestSizeEvictionClearsIndex()
        {
            _clock.SetDateTime(DateTime.Now.Add(TimeSpan.FromDays(1)));
            ICacheKey key1 = PutOneThingInCache();
            ICacheKey key2 = new SimpleCacheKey("bar");
            ICacheKey key3 = new SimpleCacheKey("duck");

            byte[] value2 = new byte[(int)FILE_CACHE_MAX_SIZE_HIGH_LIMIT];
            value2[80] = 99; // 'c'
            IWriterCallback callback = WriterCallbacks.From(value2);

            _clock.SetDateTime(DateTime.Now.Add(TimeSpan.FromDays(2)));
            _cache.Insert(key2, callback);

            // Now over limit. Next write will evict key1
            _clock.SetDateTime(DateTime.Now.Add(TimeSpan.FromDays(3)));
            _cache.Insert(key3, callback);
            Assert.IsFalse(_cache.HasKeySync(key1));
            Assert.IsFalse(_cache.HasKey(key1));
            Assert.IsTrue(_cache.HasKeySync(key3));
            Assert.IsTrue(_cache.HasKey(key3));
        }
Esempio n. 12
0
        public void TestCacheFile()
        {
            if (!_cacheDirectory.Exists)
            {
                throw new Exception("Cannot create cache dir");
            }

            // Write non-cache, non-lru file in the cache directory
            FileInfo unexpected1 = new FileInfo(
                Path.Combine(_cacheDirectory.FullName, "unexpected1"));

            using (FileStream unexpected1Fs = unexpected1.OpenWrite())
            {
                unexpected1Fs.Write(new byte[110], 0, 110);
            }

            // Touch the non-cache, non-lru file, and assert that it succeeds.
            _clock.SetDateTime(DateTime.Now.AddHours(1));
            unexpected1.LastWriteTime = _clock.Now;

            // 1. Add first cache file
            ICacheKey key1 = new SimpleCacheKey("foo");

            byte[] value1 = new byte[101];
            value1[80] = 99; // 'c', just so it's not all zeros for the equality test below.
            _cache.Insert(key1, WriterCallbacks.From(value1));

            // Verify resource
            CollectionAssert.AreEqual(value1, GetContents(GetResource(key1)));

            // 1. Touch the LRU file, and assert that it succeeds.
            _clock.SetDateTime(DateTime.Now.AddHours(2));
            Assert.IsTrue(_cache.Probe(key1));

            // The cache size should be the size of the first file only
            // The unexpected files should not count towards size
            Assert.IsTrue(_cache.Size == 101);

            // Write another non-cache, non-lru file in the cache directory
            FileInfo unexpected2 = new FileInfo(
                Path.Combine(_cacheDirectory.FullName, "unexpected2"));

            using (FileStream unexpected2Fs = unexpected2.OpenWrite())
            {
                unexpected2Fs.Write(new byte[120], 0, 120);
            }

            // Touch the non-cache, non-lru file, and assert that it succeeds.
            _clock.SetDateTime(DateTime.Now.AddHours(3));
            unexpected2.LastWriteTime = _clock.Now;

            // 2. Add second cache file
            ICacheKey key2 = new SimpleCacheKey("bar");

            byte[] value2 = new byte[102];
            value2[80] = 100; // 'd', just so it's not all zeros for the equality test below.
            _cache.Insert(key2, WriterCallbacks.From(value2));

            // 2. Touch the LRU file, and assert that it succeeds.
            _clock.SetDateTime(DateTime.Now.AddHours(4));
            Assert.IsTrue(_cache.Probe(key2));

            // The cache size should be the size of the first + second cache files
            // The unexpected files should not count towards size
            Assert.IsTrue(_cache.Size == 203);

            // At this point, the filecache size has exceeded
            // FILE_CACHE_MAX_SIZE_HIGH_LIMIT. However, eviction will be triggered
            // only when the next value will be inserted (to be more particular,
            // before the next value is inserted).

            // 3. Add third cache file
            ICacheKey key3 = new SimpleCacheKey("foobar");

            byte[] value3 = new byte[103];
            value3[80] = 101; // 'e', just so it's not all zeros for the equality test below.
            _cache.Insert(key3, WriterCallbacks.From(value3));

            // At this point, the first file should have been evicted. Only the
            // files associated with the second and third entries should be in cache.

            // 1. Verify that the first cache, lru files are deleted
            Assert.IsNull(GetResource(key1));

            // Verify the first unexpected file is deleted, but that eviction stops
            // before the second unexpected file
            Assert.IsFalse(unexpected1.Exists);
            Assert.IsFalse(unexpected2.Exists);

            // 2. Verify the second cache, lru files exist
            CollectionAssert.AreEqual(value2, GetContents(GetResource(key2)));

            // 3. Verify that cache, lru files for third entry still exists
            CollectionAssert.AreEqual(value3, GetContents(GetResource(key3)));

            // The cache size should be the size of the second + third files
            Assert.IsTrue(_cache.Size == 205, $"Expected cache size of 205 but is { _cache.Size }");

            // Write another non-cache, non-lru file in the cache directory
            FileInfo unexpected3 = new FileInfo(
                Path.Combine(_cacheDirectory.FullName, "unexpected3"));

            using (FileStream unexpected3Fs = unexpected3.OpenWrite())
            {
                unexpected3Fs.Write(new byte[120], 0, 120);
            }

            Assert.IsTrue(unexpected3.Exists);

            // After a clear, cache file size should be uninitialized (-1)
            _cache.ClearAll();
            Assert.AreEqual(-1, _cache.Size);
            unexpected3.Refresh();
            Assert.IsFalse(unexpected3.Exists);
            Assert.IsNull(GetResource(key2));
            Assert.IsNull(GetResource(key3));
        }