public async Task SubscriberEnabled_OnKeyChangedExternally_NotificationRaisedAsExpected(KeyEventType eventTypes) { var keyPrefix = Guid.NewGuid().ToString(); using var connection = BuildConnection(); using var cache1 = BuildRedisCache(connection, keyPrefix: keyPrefix, keyEventTypesToSubscribeTo: eventTypes); using var cache2 = BuildRedisCache(connection, keyPrefix: keyPrefix); var values = Enumerable .Range(0, 10) .Select(i => new KeyValuePair <int, TestClass>(i, new TestClass(i))) .ToArray(); var expectedEvents = new List <(string, KeyEventType)>(); if (eventTypes.HasFlag(KeyEventType.Set)) { expectedEvents.AddRange(values.Select(kv => (kv.Key.ToString(), KeyEventType.Set))); } if (eventTypes.HasFlag(KeyEventType.Del)) { expectedEvents.Add(("1", KeyEventType.Del)); } if (eventTypes.HasFlag(KeyEventType.Expired)) { expectedEvents.AddRange(values.Skip(2).Select(kv => (kv.Key.ToString(), KeyEventType.Expired))); } expectedEvents = expectedEvents .OrderBy(t => t.Item1) .ThenBy(t => t.Item2) .ToList(); using var countdown = new CountdownEvent(expectedEvents.Count); var keysChangedRemotely = new ConcurrentBag <(string, KeyEventType)>(); using var _ = cache1.KeysChangedRemotely.Subscribe(t => { keysChangedRemotely.Add((t.Key, t.EventType)); countdown.Signal(); }); await cache1 .SetMany(values, TimeSpan.FromSeconds(10)) .ConfigureAwait(false); await Task.Delay(TimeSpan.FromSeconds(2)).ConfigureAwait(false); keysChangedRemotely.Should().BeEmpty(); await cache2 .SetMany(values.ToArray(), TimeSpan.FromMilliseconds(500)) .ConfigureAwait(false); await cache1.TryRemove(0).ConfigureAwait(false); await cache2.TryRemove(1).ConfigureAwait(false); countdown.Wait(TimeSpan.FromSeconds(10)).Should().BeTrue(); keysChangedRemotely.OrderBy(t => t.Item1).ThenBy(t => t.Item2).Should().BeEquivalentTo(expectedEvents); }