public async Task WhenSecondSubscriber_ReuseMasterConnection() { var cache = new SimpleCache <int, TestResource>(); var masterInformer = Substitute.For <IInformer <TestResource> >(); var scheduler = new TestScheduler(); masterInformer.GetResource(ResourceStreamType.ListWatch) .Returns(TestData.Events.ResetWith2_Delay_UpdateToEach.ToTestObservable(scheduler)); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); var tcs = new TaskCompletionSource <IList <ResourceEvent <TestResource> > >(); // we attach after first subscription messages are established, but before any "watch" updates come in scheduler.ScheduleAbsolute(50, async() => { scheduler.Stop(); // need to pause virtual time brifly since child subscribers runs on separate thread and needs to be in position before we resume sending messages to master var _ = Task.Delay(10).ContinueWith(x => scheduler.Start()); var second = await sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); tcs.SetResult(second); }); await sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); await masterInformer.Received(1).GetResource(ResourceStreamType.ListWatch); }
public void IncompleteResetOnMasterWithException_ReceivedExceptionWithNoData() { var cache = new SimpleCache <int, TestResource>(); var masterInformer = Substitute.For <IInformer <TestResource> >(); masterInformer.GetResource(ResourceStreamType.ListWatch).Returns( Observable.Create <ResourceEvent <TestResource> >(obs => { obs.OnNext(new TestResource(1).ToResourceEvent(EventTypeFlags.ResetStart)); obs.OnError(new TestCompleteException()); return(Disposable.Empty); })); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); var observable = sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); var dataReceived = false; var testComplete = new TaskCompletionSource <bool>(); observable.Subscribe( x => dataReceived = true, e => testComplete.TrySetException(e), () => testComplete.SetResult(true)); Func <Task <bool> > act = async() => await testComplete.Task.TimeoutIfNotDebugging(); act.Should().Throw <TestCompleteException>(); dataReceived.Should().BeFalse(); }
public async Task ComputedEvents(string description, ScheduledEvent <TestResource>[] scenario, ResourceEvent <TestResource>[] expected, IEqualityComparer <TestResource> comparer = null) { var masterInformer = Substitute.For <IInformer <TestResource> >(); masterInformer.GetResource(ResourceStreamType.ListWatch).Returns(scenario.ToTestObservable()); _log.LogInformation("==============================================================================="); _log.LogInformation(description); var cache = new SimpleCache <int, TestResource>(); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); var observable = sharedInformer .GetResource(ResourceStreamType.ListWatch) .ComputeMissedEventsBetweenResets(x => x.Key, comparer) .TimeoutIfNotDebugging() .ToList(); var results = await observable; results.Should().NotBeEmpty(); results.Should().BeEquivalentTo(expected); }
public async Task FirstSubscriber(string description, ScheduledEvent <TestResource>[] scenario, ResourceEvent <TestResource>[] expected) { for (int i = 0; i < 1000; i++) { _log.LogInformation("==============================================================================="); _log.LogInformation(description); var cache = new SimpleCache <int, TestResource>(); var masterInformer = Substitute.For <IInformer <TestResource> >(); masterInformer.GetResource(ResourceStreamType.ListWatch).Returns(scenario.ToTestObservable()); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); var observable = sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); var results = await observable; results.Should().NotBeEmpty(); results.Should().BeEquivalentTo(expected); } }
public async Task SecondSubscriber(string description, ScheduledEvent <TestResource>[] scenario, ResourceEvent <TestResource>[] expected) { _log.LogInformation("==============================================================================="); _log.LogInformation(description); var cache = new SimpleCache <int, TestResource>(); var masterInformer = Substitute.For <IInformer <TestResource> >(); var scheduler = new TestScheduler(); masterInformer.GetResource(ResourceStreamType.ListWatch) .Returns(scenario.ToTestObservable(scheduler)); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); var tcs = new TaskCompletionSource <IList <ResourceEvent <TestResource> > >(); // we attach after first subscription messages are established, but before any "watch" updates come in scheduler.ScheduleAbsolute(50, async() => { scheduler.Stop(); // need to pause virtual time briefly since child subscribers runs on separate thread and needs to be in position before we resume sending messages to master var pause = Task.Delay(10).ContinueWith(x => scheduler.Start()); var second = await sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); tcs.SetResult(second); }); await sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); var secondResults = await tcs.Task; secondResults.Should().NotBeEmpty(); secondResults.Should().BeEquivalentTo(expected); }
public async Task SubscribeAndUnsubscribe_WhenLastSubscriber_ClosesMasterConnection() { var cache = new SimpleCache <int, TestResource>(); var masterInformer = Substitute.For <IInformer <TestResource> >(); var closeCalled = false; var scheduler = new TestScheduler(); masterInformer.GetResource(ResourceStreamType.ListWatch) .Returns(Observable.Create <ResourceEvent <TestResource> >(observer => new CompositeDisposable(TestData.Events .EmptyReset_Delay_Add .ToTestObservable(scheduler) .TimeoutIfNotDebugging() .Subscribe(observer), Disposable.Create(() => closeCalled = true)))); var sharedInformer = new SharedInformer <int, TestResource>(masterInformer, _log, x => x.Key, cache); await sharedInformer .GetResource(ResourceStreamType.ListWatch) .TimeoutIfNotDebugging() .ToList(); closeCalled.Should().BeTrue(); }