public static void Subscribe_PublishesExactSequenceOfItemsOverMultipleElapsedIntervals()
        {
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, 20, DurableJobQueueMonitor.DefaultPollingInterval, scheduler);

            List<Incoming> incomingItems = new List<Incoming>();

            var queuedItems = Enumerable.Repeat(Item.From(new Incoming() { Id = 1 }), 5)
                .Concat(new [] { Item.None<Incoming>() })
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 2 }), 5))
                .Concat(new [] { Item.None<Incoming>() })
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 1 }), 2))
                .Concat(new [] { Item.None<Incoming>() }).ToArray();

            using (var subscription = monitor.Subscribe(publishedItem =>{ incomingItems.Add(publishedItem);}))
            {
                A.CallTo(() => jobStorage.NextQueuedItem()).ReturnsNextFromSequence(queuedItems);

                scheduler.AdvanceBy(monitor.PollingInterval);
                scheduler.AdvanceBy(monitor.PollingInterval);
                scheduler.AdvanceBy(monitor.PollingInterval);

                Assert.True(queuedItems.Where(item => item.Success)
                .Select(item => item.Value)
                .SequenceEqual(incomingItems, GenericEqualityComparer<Incoming>.ByAllMembers()));
            }
        }
        public void PublishReconnect()
        {
            var scheduler = new HistoricalScheduler ();
            var source = Observable.Interval (TimeSpan.FromMilliseconds (50), scheduler);

            int result = 0;
            var published = source.Publish ();
            var pdis1 = published.Subscribe (i => result++);
            Assert.AreEqual (0, result, "#0");
            var cdis1 = published.Connect ();
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (200)); // should be enough to receive some events
            Assert.AreEqual (4, result, "#1");
            pdis1.Dispose ();
            cdis1.Dispose (); // disconnect
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (200)); // should be enough to raise interval event if it were active (which should *not*)
            Assert.AreEqual (4, result, "#2");

            // Step 2: Without any *new* subscription, it does not result in events.
            var cdis2 = published.Connect ();
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (200)); // should be enough to receive some events
            Assert.AreEqual (4, result , "#3");
            cdis2.Dispose ();

            // Step 3: with new subscription, it should result in events again.
            var pdis3 = published.Subscribe (i => result++);
            var cdis3 = published.Connect (); // without any *new* subscription, it does not result in events.
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (200)); // should be enough to receive some events
            Assert.AreEqual (8, result , "#3");
            cdis3.Dispose ();
            pdis3.Dispose (); // This should not result in NRE (possibly because of the internal cleanup). Note that this is in reverse order to pdis1
        }
 public void Clock()
 {
     var scheduler = new HistoricalScheduler ();
     Assert.AreEqual (DateTimeOffset.MinValue, scheduler.Clock, "#1"); // default
     scheduler.AdvanceBy (TimeSpan.FromDays (1));
     Assert.AreEqual (DateTimeOffset.MinValue.AddDays (1), scheduler.Clock, "#2");
     scheduler.AdvanceTo (new DateTimeOffset (2012, 1, 1, 0, 0, 0, TimeSpan.Zero));
     Assert.AreEqual (2012, scheduler.Clock.Year, "#3");
 }
 public void RecursiveActionTimeSpan2()
 {
     int i = 0;
     var scheduler = new HistoricalScheduler ();
     var span = TimeSpan.FromMilliseconds (50);
     scheduler.Schedule<object> (null, span, (object obj,Action<object,TimeSpan> a) => { i++; a (obj, span); });
     scheduler.AdvanceBy (TimeSpan.FromSeconds (1));
     Assert.AreEqual (20, i, "#1");
 }
        public void SetUp()
        {
            _tradeRepo = Substitute.For<ITradeRepository>();
            _analyticsService = Substitute.For<IAnalyticsService>();
            _executionService = Substitute.For<IExecutionService>();
            _lastValueCache = Substitute.For<IPriceLastValueCache>();

            _scheduler = new HistoricalScheduler();
            _scheduler.AdvanceTo(DateTimeOffset.Now);

            _schedulerService = Substitute.For<ISchedulerService>();
            _schedulerService.ThreadPool.Returns(_scheduler);
        }
 public void AdvanceByRaisesEvent2()
 {
     // This is actually very complicated pattern of error, caused by all of:
     // - Concat() when it internally uses SerialDisposable instead of CompositeDisposable.
     // - Delay() with non-zero duration.
     // - Delay() with non-CurrentThreadScheduler.
     var scheduler = new HistoricalScheduler ();
     var o = Observable.Empty<int> (scheduler).Delay (TimeSpan.FromSeconds (1), scheduler);
     bool done = false;
     Observable.Range (0, 3).Concat (o).Subscribe (v => {}, () => done = true);
     scheduler.AdvanceBy (TimeSpan.FromSeconds (2));
     Assert.IsTrue (done, "#1");
 }
 public void PublishLast()
 {
     var scheduler = new HistoricalScheduler ();
     var hot = Observable.Interval (TimeSpan.FromMilliseconds (20), scheduler).Skip (4).Take (2).PublishLast ();
     hot.Connect ();
     var observable = hot.Replay ();
     observable.Connect ();
     long result = 0;
     var dis = observable.Subscribe (i => result += i);
     scheduler.AdvanceBy (TimeSpan.FromSeconds (1));
     Assert.AreEqual (5, result, "#1");
     dis.Dispose ();
     var dis2 = observable.Subscribe (i => result += i);
     Assert.AreEqual (10, result, "#2");
     dis2.Dispose ();
 }
        public static void Subscribe_CallsTransitionNextQueuedItemCorrectNumberOfTimesOverMultipleElapsedIntervals()
        {
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, 20, DurableJobQueueMonitor.DefaultPollingInterval, scheduler);

            var queuedItems = Enumerable.Repeat(Item.From(new Incoming() { Id = 1 }), 5)
                .Concat(new [] { Item.None<Incoming>() })
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 2 }), 5))
                .Concat(new [] { Item.None<Incoming>() }).ToArray();

            using (var subscription = monitor.Subscribe())
            {
                A.CallTo(() => jobStorage.NextQueuedItem()).ReturnsNextFromSequence(queuedItems);

                scheduler.AdvanceBy(monitor.PollingInterval);
                scheduler.AdvanceBy(monitor.PollingInterval);

                A.CallTo(() => jobStorage.NextQueuedItem()).MustHaveHappened(Repeated.Exactly.Times(queuedItems.Length));
            }
        }
        public void Monitor_DoesNotPumpQueueWithZeroSubscribers()
        {
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, 20, DurableJobQueueMonitor.DefaultPollingInterval, scheduler);

            A.CallTo(() => jobStorage.NextQueuedItem()).Returns(Item.From(new Incoming() { Id = 1 }));

            scheduler.AdvanceBy(monitor.PollingInterval.Add(monitor.PollingInterval));

            A.CallTo(() => jobStorage.NextQueuedItem()).MustNotHaveHappened();
        }
        public void AdvanceTo()
        {
            var s = new HistoricalScheduler();

            var list = new List <Timestamped <int> >();

            s.Schedule(Time(0), () => list.Add(new Timestamped <int>(0, s.Now)));
            s.Schedule(Time(1), () => list.Add(new Timestamped <int>(1, s.Now)));
            s.Schedule(Time(2), () => list.Add(new Timestamped <int>(2, s.Now)));
            s.Schedule(Time(10), () => list.Add(new Timestamped <int>(10, s.Now)));
            s.Schedule(Time(11), () => list.Add(new Timestamped <int>(11, s.Now)));

            s.AdvanceTo(Time(8));

            Assert.AreEqual(Time(8), s.Now);
            Assert.AreEqual(Time(8), s.Clock);

            list.AssertEqual(
                new Timestamped <int>(0, Time(0)),
                new Timestamped <int>(1, Time(1)),
                new Timestamped <int>(2, Time(2))
                );

            s.AdvanceTo(Time(8));

            Assert.AreEqual(Time(8), s.Now);
            Assert.AreEqual(Time(8), s.Clock);

            list.AssertEqual(
                new Timestamped <int>(0, Time(0)),
                new Timestamped <int>(1, Time(1)),
                new Timestamped <int>(2, Time(2))
                );

            s.Schedule(Time(7), () => list.Add(new Timestamped <int>(7, s.Now)));
            s.Schedule(Time(8), () => list.Add(new Timestamped <int>(8, s.Now)));

            ReactiveAssert.Throws <ArgumentOutOfRangeException>(() => s.AdvanceTo(Time(4)));

            Assert.AreEqual(Time(8), s.Now);
            Assert.AreEqual(Time(8), s.Clock);

            list.AssertEqual(
                new Timestamped <int>(0, Time(0)),
                new Timestamped <int>(1, Time(1)),
                new Timestamped <int>(2, Time(2))
                );

            s.AdvanceTo(Time(10));

            Assert.AreEqual(Time(10), s.Now);
            Assert.AreEqual(Time(10), s.Clock);

            list.AssertEqual(
                new Timestamped <int>(0, Time(0)),
                new Timestamped <int>(1, Time(1)),
                new Timestamped <int>(2, Time(2)),
                new Timestamped <int>(7, Time(8)),
                new Timestamped <int>(8, Time(8)),
                new Timestamped <int>(10, Time(10))
                );

            s.AdvanceTo(Time(100));

            Assert.AreEqual(Time(100), s.Now);
            Assert.AreEqual(Time(100), s.Clock);

            list.AssertEqual(
                new Timestamped <int>(0, Time(0)),
                new Timestamped <int>(1, Time(1)),
                new Timestamped <int>(2, Time(2)),
                new Timestamped <int>(7, Time(8)),
                new Timestamped <int>(8, Time(8)),
                new Timestamped <int>(10, Time(10)),
                new Timestamped <int>(11, Time(11))
                );
        }
        public void RefCount()
        {
            int side = 0;
            var scheduler = new HistoricalScheduler ();
            var source = Observable.Interval (TimeSpan.FromMilliseconds (50), scheduler).Do (i => side++);

            int result = 0;
            var published = source.Publish ();
            var connected = published.RefCount ();
            var cdis1 = connected.Subscribe (i => result++);
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (400));
            Assert.IsTrue (result > 0, "#1");
            cdis1.Dispose (); // also disconnects.

            int oldSide = side;
            scheduler.AdvanceBy (TimeSpan.FromMilliseconds (400));
            Assert.AreEqual (oldSide, side, "#2"); // no advance in sequence

            var cdis2 = connected.Subscribe (i => result++);
            scheduler.AdvanceBy (TimeSpan.FromSeconds (1));
            Assert.IsTrue (side > oldSide, "#3");
            cdis2.Dispose ();
        }
        public void Subscribe_TakesNoMoreThanMaximumSpecifiedItemsPerInterval()
        {
            int maxToSlurp = 3;
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            A.CallTo(() => jobStorage.NextQueuedItem()).Returns(Item.From(new Incoming() { Id = 1 }));
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, maxToSlurp, DurableJobQueueMonitor.DefaultPollingInterval,
            scheduler);
            var completion = new ManualResetEventSlim(false);

            List<Incoming> incomingItems = new List<Incoming>();

            using (var subscription = monitor.Subscribe(publishedItem =>
            {
                incomingItems.Add(publishedItem);
                if (incomingItems.Count >= maxToSlurp)
                {
                    completion.Set();
                }
            }))
            {
                scheduler.AdvanceBy(monitor.PollingInterval + TimeSpan.FromTicks(1));
                completion.Wait(TimeSpan.FromSeconds(3));

                Assert.Equal(maxToSlurp, incomingItems.Count);
            }
        }
        public void Subscribe_ResumesInProperQueuePositionAfterReadingMaximumDuringInterval()
        {
            int maxToSlurp = 3;
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, maxToSlurp, DurableJobQueueMonitor.DefaultPollingInterval,
            scheduler);

            List<Incoming> incomingItems = new List<Incoming>();

            var queuedItems = Enumerable.Repeat(Item.From(new Incoming() { Id = 1 }), 3)
                .Concat(new []
                {
                    Item.From(new Incoming() { Id = 456 }),
                    Item.From(new Incoming() { Id = 222 }),
                    Item.From(new Incoming() { Id = 8714 })
                })
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 5 }), 2))
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 2 }), 4))
                .Concat(Enumerable.Repeat(Item.From(new Incoming() { Id = 3 }), 3))
                .ToArray();

            A.CallTo(() => jobStorage.NextQueuedItem()).ReturnsNextFromSequence(queuedItems);

            using (var subscription = monitor.Subscribe(publishedItem =>{ incomingItems.Add(publishedItem);}))
            {
                scheduler.AdvanceBy(monitor.PollingInterval);
                scheduler.AdvanceBy(monitor.PollingInterval);

                Assert.True(queuedItems.Take(maxToSlurp * 2)
                    .Select(item => item.Value)
                    .SequenceEqual(incomingItems, GenericEqualityComparer<Incoming>.ByAllMembers()));
            }
        }
Beispiel #14
0
        public void Sleep_ArgumentChecking()
        {
            var s = new HistoricalScheduler(DateTimeOffset.Now);

            ReactiveAssert.Throws <ArgumentOutOfRangeException>(() => s.Sleep(TimeSpan.FromSeconds(-1)));
        }
 /// <summary>
 /// Simulates the time of the given loglines on the timer with the given speed
 /// runs the simulation on a different thread so this method does not block
 /// </summary>
 /// <param name="timer"></param>
 /// <param name="lines"></param>
 private void SimulateLogLines(HistoricalScheduler scheduler, List<ApacheLogLine> logLines, long speed)
 {
     Task t1 = new Task(() =>
     {
         var lastTime = logLines.First().Date;
         logLines.ForEach(logLine =>
         {
             var totalSeconds = (logLine.Date - lastTime).TotalMilliseconds;
             if (totalSeconds < 0)
                 totalSeconds = 0; //Sometimes it seems not all lines are in the correct order
             var interval = TimeSpan.FromMilliseconds(totalSeconds);
             var result = TimeSpan.FromMilliseconds(totalSeconds / (double)speed);
             lastTime = logLine.Date;
             Thread.Sleep(result);
             scheduler.AdvanceBy(interval);
         });
     });
     t1.Start();
 }
        public void Monitor_AwaitsFirstSubscriberBeforePublishing()
        {
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, 20, DurableJobQueueMonitor.DefaultPollingInterval, scheduler);

            //X items + a null terminator per each elapsed interval
            var incomingItems = Enumerable.Repeat(Item.From(new Incoming() { Id = 2 }), 5)
                .Concat(new[] { Item.None<Incoming>(), Item.None<Incoming>() }).ToArray();

            A.CallTo(() => jobStorage.NextQueuedItem()).ReturnsNextFromSequence(incomingItems);

            //advance the amount of time that would normally cause our queue to be totally flushed
            scheduler.AdvanceBy(monitor.PollingInterval.Add(monitor.PollingInterval));
            using (var subscription = monitor.Subscribe())
            {
                //and now that we have a subscriber, elapse enough time to publish the queue contents
                scheduler.AdvanceBy(monitor.PollingInterval);
                scheduler.AdvanceBy(monitor.PollingInterval);

                //our transition method should have been called X times based on the list of valid items + 1 time for the null on the first scheduled execution, then an additional time w/ null for the next scheduled execution
                A.CallTo(() => jobStorage.NextQueuedItem()).MustHaveHappened(Repeated.Exactly.Times(incomingItems.Length));
            }
        }
Beispiel #17
0
 public void TearDown()
 {
     this.game = null;
     this.scheduler = null;
 }
Beispiel #18
0
 public void SetUp()
 {
     this.scheduler = new HistoricalScheduler();
     scheduler.AdvanceTo(GameStartDateTimeOffset);
     this.game = new Okazuki.TenSecGame.Models.TenSecGame(scheduler);
 }
        public void Monitor_PollsOnSpecifiedInterval(int minutes)
        {
            var jobStorage = A.Fake<IDurableJobQueue<Incoming, Incoming>>();
            var scheduler = new HistoricalScheduler();
            var interval = TimeSpan.FromMinutes(minutes);
            var monitor = new DurableJobQueueMonitor<Incoming, Incoming>(jobStorage, 20, interval, scheduler);

            using (var subscription = monitor.Subscribe())
            {
                A.CallTo(() => jobStorage.NextQueuedItem()).Returns(Item.From(new Incoming() { Id = 1 }));

                //this is a little hacky, but give ourselves a 2 second timespan to make the call against our fake
                scheduler.AdvanceBy(interval - TimeSpan.FromSeconds(2));
                A.CallTo(() => jobStorage.NextQueuedItem()).MustNotHaveHappened();
            }
        }
Beispiel #20
0
        public void AdvanceBy_ArgumentChecking()
        {
            var s = new HistoricalScheduler();

            ReactiveAssert.Throws <ArgumentOutOfRangeException>(() => s.AdvanceBy(TimeSpan.FromSeconds(-1)));
        }