public void ItAllowsBurstOfEvents()
        {
            log.WriteLine("Starting test at " + DateTimeOffset.UtcNow.ToString("HH:mm:ss.fff"));

            // Arrange
            const int EVENTS    = 40;
            const int MAX_SPEED = EVENTS / 2;

            var target = new PerSecondCounter(MAX_SPEED, "test", this.targetLogger);

            // Act
            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            for (var i = 0; i < EVENTS; i++)
            {
                target.IncreaseAsync(CancellationToken.None).Wait(Constants.TEST_TIMEOUT);
            }

            // Assert
            var    timepassed  = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - now;
            double actualSpeed = (double)EVENTS * 1000 / timepassed;

            log.WriteLine("Time passed: {0} msecs", timepassed);
            log.WriteLine("Speed: {0} events/sec", actualSpeed);
            Assert.InRange(actualSpeed, EVENTS * 0.9, EVENTS);
        }
        public void ItObtainsTheDesiredFrequency_OneEventPerSecond()
        {
            log.WriteLine("Starting test at " + DateTimeOffset.UtcNow.ToString("HH:mm:ss.fff"));

            // Arrange
            const int EVENTS    = 10;
            const int MAX_SPEED = 1;
            // When calculating the speed achieved, exclude the events in the last second
            const int EVENTS_TO_IGNORE = 1;
            var       target           = new PerSecondCounter(MAX_SPEED, "test", this.targetLogger);

            // Act
            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            for (var i = 0; i < EVENTS; i++)
            {
                target.IncreaseAsync(CancellationToken.None).Wait(Constants.TEST_TIMEOUT);
                Thread.Sleep(100);
            }

            // Assert
            var timepassed = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - now;

            double actualSpeed = (double)(EVENTS - EVENTS_TO_IGNORE) * 1000 / timepassed;

            log.WriteLine("Time passed: {0} msecs", timepassed);
            log.WriteLine("Speed: {0} events/sec", actualSpeed);
            Assert.InRange(actualSpeed, MAX_SPEED * 0.9, MAX_SPEED);
        }
        public void ItObtainsTheDesiredFrequency_SeveralEventsPerSecond()
        {
            log.WriteLine("Starting test at " + DateTimeOffset.UtcNow.ToString("HH:mm:ss.fff"));

            // Arrange
            const int EVENTS    = 41;
            const int MAX_SPEED = 20;
            // TODO: investigate why this is needed, is the rate limiting not working correctly?
            //       https://github.com/Azure/device-simulation-dotnet/issues/127
            const double PRECISION = 0.05; // empiric&acceptable value looking at CI builds

            // When calculating the speed achieved, exclude the events in the last second
            const int EVENTS_TO_IGNORE = 1;

            var target = new PerSecondCounter(MAX_SPEED, "test", this.targetLogger);

            // Act
            var now  = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            var last = now;

            for (var i = 0; i < EVENTS; i++)
            {
                target.IncreaseAsync(CancellationToken.None).Wait(Constants.TEST_TIMEOUT);
                last = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
            }

            // Assert
            //long timepassed = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - now;
            long   timepassed  = last - now;
            double actualSpeed = (double)(EVENTS - EVENTS_TO_IGNORE) * 1000 / timepassed;

            log.WriteLine("Time passed: {0} msecs", timepassed);
            log.WriteLine("Speed: {0} events/sec", actualSpeed);
            Assert.InRange(actualSpeed, MAX_SPEED - (1 + PRECISION), MAX_SPEED + PRECISION);
        }
Exemple #4
0
        public void Basic()
        {
            var tps = new PerSecondCounter();

            while (DateTime.Now.Millisecond > 100)
            {
                Thread.Sleep(1);
            }                                                            // just wait to get more of a second

            tps.Increment();
            tps.Increment(2);

            Assert.Equal(0, tps.Value);
            Assert.Equal(0.0, tps.ValuePerSecond);

            Thread.Sleep(1000);

            Assert.Equal(3, tps.Value);
            Assert.Equal(3.0, tps.ValuePerSecond);

            Thread.Sleep(1000);

            Assert.Equal(0, tps.Value);
            Assert.Equal(0.0, tps.ValuePerSecond);
        }
Exemple #5
0
        public void ItSupportLongPeriodsWithoutEvents()
        {
            log.WriteLine("Starting test at " + DateTimeOffset.UtcNow.ToString("HH:mm:ss.fff"));

            // Arrange
            const int MAX_SPEED = 10;
            const int EVENTS1   = 65;
            const int EVENTS2   = 35;
            var       target    = new PerSecondCounter(MAX_SPEED, "test", this.targetLogger);

            // Act - Run 2 separate burst, separate by a pause long enough
            // for the internal queue to be cleaned up.
            var t1 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            for (var i = 0; i < EVENTS1; i++)
            {
                target.IncreaseAsync(CancellationToken.None).Wait(TEST_TIMEOUT);
            }
            var t2 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            Thread.Sleep(5001);

            var t3 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            for (var i = 0; i < EVENTS2; i++)
            {
                target.IncreaseAsync(CancellationToken.None).Wait(TEST_TIMEOUT);
            }
            var t4 = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            // Assert
            Assert.InRange(t2 - t1, 6000, 7000);
            Assert.InRange(t4 - t3, 3000, 4000);
        }
Exemple #6
0
 public void ThrowOnOutOfRange()
 {
     Assert.Throws <ArgumentOutOfRangeException>(() => {
         var _ = new PerSecondCounter(99);
     });
     Assert.Throws <ArgumentOutOfRangeException>(() => {
         var _ = new PerSecondCounter(10001);
     });
 }
        public void ItWorksWhenNoThrottlingIsNeeded()
        {
            // Arrange
            var target = new PerSecondCounter(10, "test", this.targetLogger);

            // Act
            for (var i = 0; i < 10; i++)
            {
                // Assert - there was no pause
                Assert.False(target.IncreaseAsync(CancellationToken.None).Result);
                Task.Delay(250).Wait();
            }
        }
        public void ItPausesWhenNeeded()
        {
            log.WriteLine("Starting test at " + DateTimeOffset.UtcNow.ToString("HH:mm:ss.fff"));

            // Arrange
            const int MAX_SPEED = 60;
            const int EVENTS    = MAX_SPEED + 1;
            var       target    = new PerSecondCounter(MAX_SPEED, "test", this.targetLogger);

            // Act
            var paused = false;

            for (var i = 0; i < EVENTS; i++)
            {
                paused = target.IncreaseAsync(CancellationToken.None).Result;
            }

            // Assert
            Assert.True(paused);
        }
Exemple #9
0
        public static void Run()
        {
            Terminal.Clear();
            Terminal.WriteLine(" Terminal ", ConsoleColor.Yellow, ConsoleColor.DarkGray);
            Terminal.WriteLine();

            using var counter = new PerSecondCounter();
            counter.Tick      = delegate {
                Console.WriteLine($"TPS: {counter.ValuePerSecond} /s");
            };

            var limiter = new PerSecondLimiter(13);

            while (true)
            {
                foreach (var key in Terminal.ReadAvailableKeys())
                {
                    switch (key)
                    {
                    case ConsoleKey.OemPlus: limiter.PerSecondRate += 1; break;

                    case ConsoleKey.OemMinus:
                        if (limiter.PerSecondRate > 1)
                        {
                            limiter.PerSecondRate -= 1;
                        }
                        break;

                    case ConsoleKey.Escape: return;
                    }
                }

                limiter.Wait();
                counter.Increment();
            }
        }
        public void FourThreadsTwentyPerSecondAreThrottledTogether()
        {
            // Arrange
            var events  = new ConcurrentBag <DateTimeOffset>();
            var target  = new PerSecondCounter(20, "test", this.targetLogger);
            var thread1 = new Thread(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    target.IncreaseAsync(CancellationToken.None).Wait();
                    events.Add(DateTimeOffset.UtcNow);
                }
            });
            var thread2 = new Thread(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    target.IncreaseAsync(CancellationToken.None).Wait();
                    events.Add(DateTimeOffset.UtcNow);
                }
            });
            var thread3 = new Thread(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    target.IncreaseAsync(CancellationToken.None).Wait();
                    events.Add(DateTimeOffset.UtcNow);
                }
            });
            var thread4 = new Thread(() =>
            {
                for (int i = 0; i < 10; i++)
                {
                    target.IncreaseAsync(CancellationToken.None).Wait();
                    events.Add(DateTimeOffset.UtcNow);
                }
            });

            // Act
            while (DateTimeOffset.UtcNow.Millisecond > 200)
            {
                // wait until the next second
            }

            var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();

            thread1.Start();
            thread2.Start();
            thread3.Start();
            thread4.Start();
            thread1.Join();
            thread2.Join();
            thread3.Join();
            thread4.Join();

            // Assert
            var passed = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - now;
            var j      = 0;

            foreach (var e in events.ToImmutableSortedSet())
            {
                j++;
                log.WriteLine(j + ": " + e.ToString("hh:mm:ss.fff"));
            }

            log.WriteLine("time: " + passed);
            Assert.InRange(passed, 1000, 1500);
        }