public Market GetMarket(MarketConfiguration configuration)
        {
            var market = new Market(configuration, LoggerForTests <Market> .Default(), _eventSerializer);

            _actors.Add(market);

            return(market);
        }
        public async Task ShouldCheckMinimumPerformance()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfiguration = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint       = ToPublishersEndpoint,
                HeartbeatEndpoint    = HeartbeatEndpoint,
                PriceGenerationDelay = TimeSpan.FromMilliseconds(20)
            };

            var market = GetMarket(marketConfiguration);

            await router.Run();

            await market.Run();

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromMilliseconds(500),
                HeartbeatTimeout = TimeSpan.FromSeconds(1)
            };

            var cache = GetCache(cacheConfiguration);

            await cache.Run();

            await WaitForCachesToCaughtUp(cache);

            await Task.Delay(2000);

            var cacheItemsEvents = cache.Items
                                   .SelectMany(items => items.AppliedEvents)
                                   .ToList();


            //when run as standalone test, we should expect 100%
            //when run in a test batch, the result is less deterministic, thus we lower to 70%
            Assert.Greater((double)cacheItemsEvents.Count / (double)market.Prices.Count, 0.70);
        }
Esempio n. 3
0
        public async Task ShouldProduceEventsAndConsumeThemViaEventCache()
        {
            var marketConfiguration = new MarketConfiguration("TEST")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromSeconds(1),
                HeartbeatTimeout  = TimeSpan.FromSeconds(1)
            };

            var producer = new Market(marketConfiguration, LoggerForTests <Market> .Default(), _eventSerializer);
            await producer.Run();

            await Task.Delay(2000);

            var eventCountOnProducer = producer.Prices.Count;
            var eventsOnEventCache   = (await _eventCache.GetAllStreams())
                                       .Select(msg => _serializer.Deserialize <ChangeCcyPairPrice>(msg.ProducerMessage.MessageBytes))
                                       .ToList();

            Assert.Greater(eventCountOnProducer, 0);
            Assert.Greater(eventsOnEventCache.Count, 0);
            Assert.AreEqual(eventCountOnProducer, eventsOnEventCache.Count);

            Assert.IsTrue(eventsOnEventCache.All(ev => producer.Prices.Any(p => p.Ask == ev.Ask)));

            producer.Publish(new ChangeCcyPairPrice("TEST", "TEST-Market", 0.0, 0.0, 0.0, 0.0));

            await Task.Delay(200);

            var testEvent = await _eventCache.GetStream("TEST");

            Assert.AreEqual(1, testEvent.Count());

            await producer.Destroy();
        }
        public async Task ShouldSubscribeToSubject()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfigurationFxConnect = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint       = ToPublishersEndpoint,
                HeartbeatEndpoint    = HeartbeatEndpoint,
                PriceGenerationDelay = TimeSpan.FromMilliseconds(500)
            };

            var marketConfigurationHarmony = new MarketConfiguration("Harmony")
            {
                BrokerEndpoint       = ToPublishersEndpoint,
                HeartbeatEndpoint    = HeartbeatEndpoint,
                PriceGenerationDelay = TimeSpan.FromMilliseconds(500)
            };

            var market1 = GetMarket(marketConfigurationFxConnect);
            var market2 = GetMarket(marketConfigurationHarmony);

            var cacheConfigurationEuroDol = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject = "EUR/USD"
            };

            var cacheConfigurationEuroDolFxConnect = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject = "EUR/USD.FxConnect"
            };

            var cacheEuroDol          = GetCache(cacheConfigurationEuroDol);
            var cacheEuroDolFxConnect = GetCache(cacheConfigurationEuroDolFxConnect);

            await router.Run();

            await Task.Delay(1000);

            await market1.Run();

            await market2.Run();

            await Task.Delay(2000);

            await cacheEuroDol.Run();

            await cacheEuroDolFxConnect.Run();

            await WaitForCachesToCaughtUp(cacheEuroDol, cacheEuroDolFxConnect);

            var routerEventCacheItems = (await _eventCache.GetStreamBySubject(string.Empty)).ToList();

            Assert.Greater(routerEventCacheItems.Count(), 0);

            var ccyPairsCacheEuroDol = cacheEuroDol.Items
                                       .SelectMany(item => item.AppliedEvents)
                                       .Select(item => item.Subject)
                                       .Distinct()
                                       .ToList();

            var ccyPairsCacheEuroDolFxConnect = cacheEuroDolFxConnect.Items
                                                .SelectMany(item => item.AppliedEvents)
                                                .Select(item => item.Subject)
                                                .Distinct()
                                                .ToList();

            while (market1.Prices.GroupBy(p => p.EventStreamId).Count() != 2)
            {
                await Task.Delay(500);
            }

            // EUR/USD.FxConnect & EUR/USD.Harmony
            Assert.AreEqual(2, ccyPairsCacheEuroDol.Count());
            Assert.IsTrue(ccyPairsCacheEuroDol.All(subject => subject.EndsWith("FxConnect") || subject.EndsWith("Harmony")));
            Assert.IsTrue(ccyPairsCacheEuroDol.All(subject => subject.StartsWith(cacheConfigurationEuroDol.Subject)));

            var cacheEvents = cacheEuroDol.Items
                              .SelectMany(item => item.AppliedEvents)
                              .Cast <IEvent <string, CurrencyPair> >()
                              .GroupBy(ev => ev.EventStreamId)
                              .ToList();

            foreach (var grp in cacheEvents)
            {
                var index = 0;

                foreach (var ev in grp)
                {
                    Assert.AreEqual(index++, ev.Version);
                }
            }

            // EUR/USD.FxConnect
            Assert.AreEqual(1, ccyPairsCacheEuroDolFxConnect.Count());
            Assert.AreEqual(cacheConfigurationEuroDolFxConnect.Subject, ccyPairsCacheEuroDolFxConnect.First());
        }
        public async Task ShouldRetrievedEventsSequentially()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var marketConfigurationFxConnect = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint
            };

            var marketConfigurationHarmony = new MarketConfiguration("Harmony")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint
            };

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromSeconds(10),
                HeartbeatTimeout = TimeSpan.FromSeconds(2)
            };

            var router = GetBrokerageService(brokerConfiguration);

            var market1 = GetMarket(marketConfigurationFxConnect);
            var market2 = GetMarket(marketConfigurationHarmony);

            var cache      = GetCache(cacheConfiguration);
            var cacheProof = GetCache(cacheConfiguration);

            await router.Run();

            await market1.Run();

            await market2.Run();

            await cache.Run();

            await cacheProof.Run();

            await WaitForCachesToCaughtUp(cache, cacheProof);

            var cacheEvents = cache.Items
                              .SelectMany(item => item.AppliedEvents)
                              .Cast <IEvent <string, CurrencyPair> >()
                              .GroupBy(ev => ev.EventStreamId)
                              .ToList();

            foreach (var grp in cacheEvents)
            {
                var index = 0;

                foreach (var ev in grp)
                {
                    Assert.AreEqual(index++, ev.Version);
                }
            }


            var cacheProofEvents = cache.Items
                                   .SelectMany(item => item.AppliedEvents)
                                   .Cast <IEvent <string, CurrencyPair> >()
                                   .GroupBy(ev => ev.EventStreamId)
                                   .ToList();

            foreach (var grp in cacheProofEvents)
            {
                var index = 0;

                foreach (var ev in grp)
                {
                    Assert.AreEqual(index++, ev.Version);
                }
            }
        }
Esempio n. 6
0
        public async Task ShouldCheckMaxPerformance()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfigurationFxConnect = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint       = ToPublishersEndpoint,
                HeartbeatEndpoint    = HeartbeatEndpoint,
                HeartbeatDelay       = TimeSpan.FromSeconds(1),
                HeartbeatTimeout     = TimeSpan.FromSeconds(1),
                PriceGenerationDelay = TimeSpan.FromMilliseconds(50)
            };

            var marketConfigurationHarmony = new MarketConfiguration("Harmony")
            {
                BrokerEndpoint       = ToPublishersEndpoint,
                HeartbeatEndpoint    = HeartbeatEndpoint,
                HeartbeatDelay       = TimeSpan.FromSeconds(1),
                HeartbeatTimeout     = TimeSpan.FromSeconds(1),
                PriceGenerationDelay = TimeSpan.FromMilliseconds(50)
            };

            var market1 = GetMarket(marketConfigurationFxConnect);
            var market2 = GetMarket(marketConfigurationHarmony);

            await router.Run();

            await Task.Delay(1000);

            await market1.Run();

            await market2.Run();

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromSeconds(1),
                HeartbeatTimeout = TimeSpan.FromSeconds(1)
            };

            var cache = GetCache(cacheConfiguration);

            await cache.Run();

            await WaitForCachesToCaughtUp(cache);

            var cacheEvents = cache.Items
                              .SelectMany(item => item.AppliedEvents)
                              .Cast <IEvent <string, CurrencyPair> >()
                              .GroupBy(ev => ev.EventStreamId)
                              .ToList();


            Assert.Greater(cacheEvents.Count, 0);

            Assert.IsTrue(cacheEvents.All(c => c.Count() > 0));

            foreach (var grp in cacheEvents)
            {
                var index = 0;

                foreach (var ev in grp)
                {
                    Assert.AreEqual(index++, ev.Version);
                }
            }
        }
        public async Task ShouldSubscribeToEventFeed()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfigurationFxConnect = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromSeconds(1),
                HeartbeatTimeout  = TimeSpan.FromSeconds(1)
            };

            var marketConfigurationHarmony = new MarketConfiguration("Harmony")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromSeconds(1),
                HeartbeatTimeout  = TimeSpan.FromSeconds(1)
            };

            var market1 = GetMarket(marketConfigurationFxConnect);
            var market2 = GetMarket(marketConfigurationHarmony);

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                HeartbeatDelay   = TimeSpan.FromSeconds(1),
                HeartbeatTimeout = TimeSpan.FromSeconds(1)
            };

            var cache = GetCache(cacheConfiguration);

            await router.Run();

            await market1.Run();

            await market2.Run();

            //create an event cache
            await Task.Delay(2000);

            var routerEventCacheItems = await _eventCache.GetStreamBySubject(string.Empty);

            Assert.Greater(routerEventCacheItems.Count(), 0);

            var counter = 0;

            var cleanup = cache.OnItemChanged
                          .Connect()
                          .Subscribe(changes =>
            {
                counter += changes.Count;
            });

            await cache.Run();

            await WaitForCachesToCaughtUp(cache);

            var eventCacheItems = cache.Items.SelectMany(item => item.AppliedEvents).ToList();

            Assert.AreEqual(eventCacheItems.Count(), counter);

            var markets = cache.Items
                          .SelectMany(item => item.AppliedEvents)
                          .Cast <ChangeCcyPairPrice>()
                          .Select(ev => ev.Market)
                          .Distinct();

            //fxconnext & harmony
            Assert.AreEqual(2, markets.Count());

            cleanup.Dispose();
        }
Esempio n. 8
0
        public async Task ShouldConnectAndDisconnectFromBroker()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var marketConfiguration = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromMilliseconds(500),
                HeartbeatTimeout  = TimeSpan.FromSeconds(1)
            };

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromMilliseconds(500),
                HeartbeatTimeout = TimeSpan.FromSeconds(1)
            };

            var router = GetBrokerageService(brokerConfiguration);
            var market = GetMarket(marketConfiguration);
            var cache  = GetCache(cacheConfiguration);

            var cacheStates = new List <DynamicCacheState>();

            var stateObservable = cache.OnStateChanged
                                  .Subscribe(state =>
            {
                cacheStates.Add(state);
            });


            await market.Run();

            await cache.Run();

            Assert.AreEqual(ProducerState.NotConnected, market.ProducerState);
            Assert.AreEqual(DynamicCacheState.NotConnected, cache.CacheState);

            await router.Run();

            await Task.Delay(1000);

            await WaitForCachesToCaughtUp(cache);

            Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState);
            Assert.AreEqual(ProducerState.Connected, market.ProducerState);

            await router.Destroy();

            await Task.Delay(2000);

            Assert.AreEqual(DynamicCacheState.Disconnected, cache.CacheState);
            Assert.AreEqual(ProducerState.Disconnected, market.ProducerState);

            router = GetBrokerageService(brokerConfiguration);

            await router.Run();

            await WaitForCachesToCaughtUp(cache);

            await Task.Delay(2000);

            Assert.AreEqual(5, cacheStates.Count);
            Assert.AreEqual(DynamicCacheState.NotConnected, cacheStates.ElementAt(0));
            Assert.AreEqual(DynamicCacheState.Connected, cacheStates.ElementAt(1));
            Assert.AreEqual(DynamicCacheState.Disconnected, cacheStates.ElementAt(2));
            Assert.AreEqual(DynamicCacheState.Reconnected, cacheStates.ElementAt(3));
            Assert.AreEqual(DynamicCacheState.Connected, cacheStates.ElementAt(4));

            Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState);
            Assert.AreEqual(ProducerState.Connected, market.ProducerState);

            stateObservable.Dispose();
        }
Esempio n. 9
0
        public void SetUp()
        {
            _eventIdProvider = new InMemoryEventIdProvider();
            _serializer      = new JsonNetSerializer();
            _eventSerializer = new EventSerializer(_serializer);
            _eventCache      = new InMemoryEventCache(_eventIdProvider, _eventSerializer);

            JsonConvert.DefaultSettings = () =>
            {
                var settings = new JsonSerializerSettings
                {
                    Formatting       = Formatting.Indented,
                    TypeNameHandling = TypeNameHandling.Objects,
                    ContractResolver = new CamelCasePropertyNamesContractResolver()
                };

                return(settings);
            };

            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfigurationFxConnect = new MarketConfiguration("FxConnect")
            {
                IsAutoGen         = false,
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromSeconds(5),
                HeartbeatTimeout  = TimeSpan.FromSeconds(5)
            };

            _market1 = GetMarket(marketConfigurationFxConnect);

            router.Run().Wait();

            Task.Delay(1000).Wait();

            _market1.Run().Wait();

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromSeconds(5),
                HeartbeatTimeout = TimeSpan.FromSeconds(5),
                ZmqHighWatermark = 1000,
                UseEventBatching = UseEventBatch,
                DoStoreEvents    = false
            };

            _cache = GetCache(cacheConfiguration);

            _cache.Run().Wait();

            WaitForCachesToCaughtUp(_cache).Wait();
        }
Esempio n. 10
0
        public async Task ShouldHandleDisconnectAndCacheRebuild()
        {
            var brokerConfiguration = new BrokerageServiceConfiguration()
            {
                HeartbeatEndpoint       = HeartbeatEndpoint,
                StateOfTheWorldEndpoint = StateOfTheWorldEndpoint,
                ToSubscribersEndpoint   = ToSubscribersEndpoint,
                ToPublisherEndpoint     = ToPublishersEndpoint
            };

            var router = GetBrokerageService(brokerConfiguration);

            var marketConfiguration = new MarketConfiguration("FxConnect")
            {
                BrokerEndpoint    = ToPublishersEndpoint,
                HeartbeatEndpoint = HeartbeatEndpoint,
                HeartbeatDelay    = TimeSpan.FromSeconds(1),
                HeartbeatTimeout  = TimeSpan.FromSeconds(1),
                IsAutoGen         = false
            };

            var market1 = GetMarket(marketConfiguration);

            var cacheConfiguration = new DynamicCacheConfiguration(ToSubscribersEndpoint, StateOfTheWorldEndpoint, HeartbeatEndpoint)
            {
                Subject          = string.Empty,
                HeartbeatDelay   = TimeSpan.FromSeconds(1),
                HeartbeatTimeout = TimeSpan.FromSeconds(1)
            };

            var cache      = GetCache(cacheConfiguration);
            var cacheProof = GetCache(cacheConfiguration);

            var cacheStates = new List <DynamicCacheState>();

            var stateObservable = cache.OnStateChanged
                                  .Subscribe(state =>
            {
                cacheStates.Add(state);
            });


            await router.Run();

            await market1.Run();

            await cache.Run();

            await cacheProof.Run();

            Assert.AreEqual(DynamicCacheState.NotConnected, cache.CacheState);
            Assert.AreEqual(DynamicCacheState.NotConnected, cacheProof.CacheState);

            await Task.Delay(1000);

            await market1.WaitUntilConnected();

            Assert.AreEqual(ProducerState.Connected, market1.ProducerState);

            market1.PublishNext();
            market1.PublishNext();
            market1.PublishNext();

            await WaitForCachesToCaughtUp(cache, cacheProof);

            Assert.AreEqual(DynamicCacheState.Connected, cache.CacheState);
            Assert.AreEqual(DynamicCacheState.Connected, cacheProof.CacheState);

            var cacheEvents      = cache.Items.SelectMany(item => item.AppliedEvents).ToList();
            var cacheProofEvents = cacheProof.Items.SelectMany(item => item.AppliedEvents).ToList();

            Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count());

            await router.Destroy();

            await Task.Delay(2000);

            Assert.AreEqual(DynamicCacheState.Disconnected, cache.CacheState);
            Assert.AreEqual(DynamicCacheState.Disconnected, cacheProof.CacheState);

            router = GetBrokerageService(brokerConfiguration);

            await router.Run();

            await Task.Delay(1000);

            market1.PublishNext();
            market1.PublishNext();
            market1.PublishNext();

            await WaitForCachesToCaughtUp(cache, cacheProof);

            var cacheCCyPair      = cache.Items.ToList();
            var cacheProofCcyPair = cacheProof.Items.ToList();

            Assert.AreEqual(cacheCCyPair.Count(), cacheProofCcyPair.Count());
            Assert.AreEqual(cacheCCyPair.Count(), cacheProofCcyPair.Count());

            foreach (var ccyPair in cacheCCyPair)
            {
                var proof = cacheProofCcyPair.First(ccy => ccy.Id == ccyPair.Id);

                Assert.AreEqual(ccyPair.Ask, proof.Ask);
                Assert.AreEqual(ccyPair.Bid, proof.Bid);
                Assert.AreEqual(ccyPair.Mid, proof.Mid);
                Assert.AreEqual(ccyPair.Spread, proof.Spread);
            }

            cacheEvents      = cacheCCyPair.SelectMany(item => item.AppliedEvents).ToList();
            cacheProofEvents = cacheProofCcyPair.SelectMany(item => item.AppliedEvents).ToList();

            Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count());
            Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count());
            Assert.AreEqual(cacheEvents.Count(), cacheProofEvents.Count());

            await Task.Delay(1000);

            Assert.AreEqual(5, cacheStates.Count);
            Assert.AreEqual(DynamicCacheState.NotConnected, cacheStates.ElementAt(0));
            Assert.AreEqual(DynamicCacheState.Connected, cacheStates.ElementAt(1));
            Assert.AreEqual(DynamicCacheState.Disconnected, cacheStates.ElementAt(2));
            Assert.AreEqual(DynamicCacheState.Reconnected, cacheStates.ElementAt(3));
            Assert.AreEqual(DynamicCacheState.Connected, cacheStates.ElementAt(4));

            stateObservable.Dispose();
        }