public async Task Cache_NonDist_Test_That_Cache_Delete_Key_Works_OK()
        {
            // ARRANGE
            var ca1 = new CacheAccessor(new CacheConfig {
                IsAuditingEnabled = true, IsCentralCacheEnabled = false
            });

            await ca1.InitialiseIfNecessaryAsync();

            var KEY   = CreateGuid();
            var VALUE = CreateGuid();

            // ACT
            await ca1.SetAsync(KEY, VALUE); // set the value

            await ca1.DeleteAsync(KEY);

            var evt1 = ca1.LastCachingEvent;
            var v2   = await ca1.GetWithMetaDataAsync <string>(KEY);

            // ASSERT
            Assert.IsNull(v2.Data);
            Assert.IsTrue(evt1 == eCacheEvent.KeyDeletedInMemory);
            Assert.IsTrue(ca1.LastCachingEvent == eCacheEvent.KeyValueGotFromMemoryAttempt);
        }
        public async Task Cache_Dist_Test_That_Cache_Delete_Key_Works_OK()
        {
            // ARRANGE
            var ca1 = new CacheAccessor(new CacheConfig {
                IsAuditingEnabled = true
            });
            var ca2 = new CacheAccessor(new CacheConfig {
                IsAuditingEnabled = true
            });

            await ca1.InitialiseIfNecessaryAsync();

            await ca2.InitialiseIfNecessaryAsync();

            var KEY   = CreateGuid();
            var VALUE = CreateGuid();

            // ACT
            await ca1.SetAsync(KEY, VALUE); // set the value

            // Wait for propagation to ca2
            await ca2.WaitForEvent(eCacheEvent.KeySetInMemory);

            var v1 = await ca2.GetWithMetaDataAsync <string>(KEY);

            await ca2.DeleteAsync(KEY);

            var propagationTimeInMS = await ca1.WaitForEvent(eCacheEvent.KeyDeletedInMemory);

            var v2 = await ca1.GetWithMetaDataAsync <string>(KEY);

            var v3 = await ca2.GetWithMetaDataAsync <string>(KEY);

            // ASSERT
            Assert.IsNotNull(v1.Data);
            Assert.IsTrue(v1.IsFromInMemoryCache);
            Assert.IsNull(v2.Data);
            Assert.IsTrue(v2.IsFromCentralCacheServer);
            Assert.IsNull(v3.Data);
            Assert.IsTrue(v3.IsFromCentralCacheServer);
        }
        public async Task Cache_Dist_TestKeyValuePairPropagation()
        {
            // Arrange
            var KEY            = Key();
            var VALUE          = CreateGuid();
            var cacheAccessor1 = new CacheAccessor(new CacheConfig {
                IsAuditingEnabled = true
            });
            var cacheAccessor2 = new CacheAccessor(new CacheConfig {
                IsAuditingEnabled = true
            });
            await cacheAccessor1.InitialiseIfNecessaryAsync();

            await cacheAccessor2.InitialiseIfNecessaryAsync();

            cacheAccessor1.AuditLog.Clear();
            cacheAccessor2.AuditLog.Clear();

            // Act
            var v1 = await cacheAccessor1.GetWithMetaDataAsync <string>(KEY);

            await cacheAccessor1.SetAsync(KEY, VALUE, TimeSpan.FromMinutes(2));

            await Task.Delay(300);

            var logOfCA2 = cacheAccessor2.AuditLog.ToArray();

            var v2 = await cacheAccessor2.GetWithMetaDataAsync <string>(KEY);

            var v3 = await cacheAccessor2.GetWithMetaDataAsync <string>(KEY);

            var cacheAccessor3 = new CacheAccessor(new CacheConfig());
            await cacheAccessor3.InitialiseIfNecessaryAsync();

            var v6 = await cacheAccessor3.GetWithMetaDataAsync <string>(KEY);

            var v7 = await cacheAccessor3.GetWithMetaDataAsync <string>(KEY);

            await cacheAccessor2.DeleteAsync(KEY);

            var v4_1 = await cacheAccessor1.GetWithMetaDataAsync <string>(KEY);

            var v5_1 = await cacheAccessor2.GetWithMetaDataAsync <string>(KEY);

            await Task.Delay(300);

            var v4 = await cacheAccessor1.GetWithMetaDataAsync <string>(KEY);

            var v5 = await cacheAccessor2.GetWithMetaDataAsync <string>(KEY);

            Assert.IsTrue(logOfCA2.First().CachingEvent == eCacheEvent.KeySetInMemory, "The next audit event should have been to receive the key update message");
            Assert.IsTrue(v1.IsFromCentralCacheServer, "Trying to get something that isn't set, should _AT_LEAST_ try the central cache");
            Assert.IsTrue(v2.IsFromInMemoryCache, "Getting an item after setting it should mean that the in-memory cache has had time to catch up");
            Assert.IsTrue(v3.IsFromInMemoryCache, "The value should have propagated to cache accessor");
            Assert.IsNull(v4.Data, "The value should be null");
            Assert.IsNull(v5.Data, "The value should be null");
            Assert.IsTrue(v4.IsFromCentralCacheServer, "If a value is null, it should have tried the central cache server");
            Assert.IsTrue(v5.IsFromCentralCacheServer, "If a value is null, it should have tried the central cache server");

            Assert.IsNotNull(v6.Data, "The data shouldn't be null");
            Assert.IsTrue(v6.IsFromCentralCacheServer, "The value should have been retrieved from the central server");

            Assert.IsNotNull(v7.Data, "The data shouldn't be null");
            Assert.AreEqual(VALUE, v7.Data);
            Assert.IsTrue(v7.IsFromInMemoryCache, "The value should have been retrieved from the memory cache");

            // This test is too subjective for the build server
            // Assert.IsTrue(v7.ElapsedMilliseconds < v6.ElapsedMilliseconds, "It should have been quicker to get the value the second time");
        }