コード例 #1
0
        public void QuickPulseQuotaTrackerShouldNotGetBursts()
        {
            // ARRANGE
            int maxQuota         = 30;
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, 0);

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));

            // ACT & ASSERT
            // Emulate that every second we try to track 100 of documents. We should expect
            // only one document every 2nd second (quota = 30 documents per min).
            for (int i = 0; i < 1000; i++)
            {
                int count = 0;
                for (int j = 0; j < 100; j++)
                {
                    bool counted = quotaTracker.ApplyQuota();
                    if (counted)
                    {
                        ++count;
                    }
                }

                Assert.AreEqual((i % 2) == 0 ? 0 : 1, count);

                mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));
            }
        }
        public void QuickPulseQuotaTrackerIsThreadSafe()
        {
            // ARRANGE
            int maxQuota = 100 * 60;
            int experimentLengthInSeconds = 1000;
            int concurrency = 1000;

            var mockTimeProvider = new ClockMock();
            var quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, 0);

            var quotaApplicationResults = new ConcurrentQueue<bool>();

            // ACT
            for (int i = 0; i < experimentLengthInSeconds; i++)
            {
                mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));

                var tasks = new List<Action>();
                for (int j = 0; j < concurrency; j++)
                {
                    tasks.Add(() => quotaApplicationResults.Enqueue(quotaTracker.ApplyQuota()));
                }

                Parallel.Invoke(new ParallelOptions() { MaxDegreeOfParallelism = concurrency }, tasks.ToArray());
            }

            // ASSERT
            var passedQuotaCount = quotaApplicationResults.Count(result => result);
            var correctResult = maxQuota / 60 * experimentLengthInSeconds;

            Assert.AreEqual(correctResult, passedQuotaCount);
            Assert.IsFalse(quotaTracker.ApplyQuota());
        }
コード例 #3
0
        public void QuickPulseQuotaTrackerQuotaGetsRefilled()
        {
            // ARRANGE
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, 30, 0);
            bool counted;

            // ACT & ASSERT
            Assert.AreEqual(0, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // No quota yet
            Assert.AreEqual(0, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1)); // 0.5 quota accumulated

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // No quota yet
            Assert.AreEqual(0.5f, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1)); // 1 quota accumulated

            counted = quotaTracker.ApplyQuota();
            Assert.IsTrue(counted);
            Assert.AreEqual(0, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // Quota was already exhausted.
            Assert.AreEqual(0, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);
        }
コード例 #4
0
        public void QuickPulseCollectionStateManagerPingRecovers()
        {
            // ARRANGE
            var timings       = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock {
                ReturnValueFromPing = false, ReturnValueFromSubmitSample = false
            };
            var actions         = new List <string>();
            var returnedSamples = new List <QuickPulseDataSample>();
            var timeProvider    = new ClockMock();
            var manager         = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState(string.Empty));

            // ACT
            serviceClient.ReturnValueFromPing = null;
            timeProvider.FastForward(timings.TimeToServicePollingBackOff.Add(TimeSpan.FromSeconds(1)));
            manager.UpdateState(string.Empty);

            timeProvider.FastForward(TimeSpan.FromMinutes(1));
            serviceClient.ReturnValueFromPing = false;

            // ASSERT
            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState(string.Empty));
        }
コード例 #5
0
        public void QuickPulseTopCpuCollectorReturnsNothingIfInitializationFailed()
        {
            // ARRANGE
            var processProvider = new QuickPulseProcessProviderMock {
                AlwaysThrow = new Exception()
            };

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", TimeSpan.FromSeconds(1))
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT
            collector.Initialize();
            collector.GetTopProcessesByCpu(5);
            timeProvider.FastForward(TimeSpan.FromSeconds(1));

            var result = collector.GetTopProcessesByCpu(5);

            // ASSERT
            Assert.IsTrue(collector.InitializationFailed);
            Assert.IsFalse(result.Any());
        }
コード例 #6
0
        public void QuickPulseCollectionStateManagerSubmitBacksOff()
        {
            // ARRANGE
            var timings       = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock {
                ReturnValueFromPing = true, ReturnValueFromSubmitSample = true
            };
            var actions         = new List <string>();
            var returnedSamples = new List <QuickPulseDataSample>();
            var timeProvider    = new ClockMock();
            var manager         = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            manager.UpdateState(string.Empty);

            // ACT & ASSERT
            Assert.AreEqual(timings.CollectionInterval, manager.UpdateState("some ikey"));

            serviceClient.ReturnValueFromSubmitSample = null;
            timeProvider.FastForward(timings.TimeToCollectionBackOff.Add(TimeSpan.FromSeconds(-1)));
            Assert.AreEqual(timings.CollectionInterval, manager.UpdateState("some ikey"));
            Assert.AreEqual(true, manager.IsCollectingData);

            timeProvider.FastForward(TimeSpan.FromSeconds(2));
            Assert.AreEqual(timings.ServicePollingBackedOffInterval, manager.UpdateState("some ikey"));
            Assert.AreEqual(false, manager.IsCollectingData);
        }
コード例 #7
0
        public void QuickPulseTopCpuCollectorRetriesAfterIntervalWhenAccessDenied()
        {
            // ARRANGE
            var processProvider = new QuickPulseProcessProviderMock();

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", TimeSpan.FromSeconds(1))
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT
            collector.Initialize();
            collector.GetTopProcessesByCpu(5);
            timeProvider.FastForward(TimeSpan.FromSeconds(1));

            var resultWhenEverythingIsFine = collector.GetTopProcessesByCpu(5);

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            processProvider.AlwaysThrow = new UnauthorizedAccessException();
            var  resultWhileAccessDenied = collector.GetTopProcessesByCpu(5);
            bool flagWhileAccessDenied   = collector.AccessDenied;

            // 60 second retry interval
            timeProvider.FastForward(TimeSpan.FromSeconds(59));
            processProvider.AlwaysThrow = null;
            var  resultWhenEverythingIsFineAgainButNotEnoughTimePassedToRetry = collector.GetTopProcessesByCpu(5);
            bool flagWhenAccessIsOkButNotEnoughTimePassed = collector.AccessDenied;

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            processProvider.AlwaysThrow = null;
            var  resultWhenRetryIntervalHasPassed = collector.GetTopProcessesByCpu(5);
            bool flagWhenRetryIntervalHasPassed   = collector.AccessDenied;

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            processProvider.AlwaysThrow = null;
            var  resultWhenEverythingIsBackToNormalForGood = collector.GetTopProcessesByCpu(5);
            bool flagWhenEverythingIsBackToNormalForGood   = collector.AccessDenied;

            // ASSERT
            Assert.IsTrue(resultWhenEverythingIsFine.Any());
            Assert.IsFalse(resultWhileAccessDenied.Any());
            Assert.IsTrue(flagWhileAccessDenied);
            Assert.IsFalse(resultWhenEverythingIsFineAgainButNotEnoughTimePassedToRetry.Any());
            Assert.IsTrue(flagWhenAccessIsOkButNotEnoughTimePassed);
            Assert.IsTrue(resultWhenRetryIntervalHasPassed.Any());
            Assert.IsFalse(flagWhenRetryIntervalHasPassed);
            Assert.IsTrue(resultWhenEverythingIsBackToNormalForGood.Any());
            Assert.IsFalse(flagWhenEverythingIsBackToNormalForGood);
        }
コード例 #8
0
        public void QuickPulseServiceClientSetsTransmissionTimeCorrectly()
        {
            // ARRANGE
            var dummy        = new Dictionary <string, Tuple <PerformanceCounterData, double> >();
            var dummy2       = Enumerable.Empty <Tuple <string, int> >();
            var timeProvider = new ClockMock();

            var serviceClient = new QuickPulseServiceClient(this.serviceEndpoint, string.Empty, string.Empty, string.Empty, string.Empty, timeProvider, false);
            var sample1       =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator {
                StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow
            },
                    dummy,
                    dummy2,
                    false);

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            var sample2 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator {
                StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow
            },
                    dummy,
                    dummy2,
                    false);

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            var sample3 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator {
                StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow
            },
                    dummy,
                    dummy2,
                    false);

            // ACT
            timeProvider.FastForward(TimeSpan.FromSeconds(5));
            serviceClient.SubmitSamples(new[] { sample1, sample2, sample3 }, string.Empty);

            // ASSERT
            this.listener.Stop();

            Assert.AreEqual(3, this.samples.Count);
            Assert.IsTrue((timeProvider.UtcNow - this.samples[0].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue((timeProvider.UtcNow - this.samples[1].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue((timeProvider.UtcNow - this.samples[2].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue(this.samples.All(s => (s.Item2.Timestamp - timeProvider.UtcNow).Duration() > TimeSpan.FromSeconds(1)));
        }
コード例 #9
0
        public void QuickPulseTopCpuCollectorReturnsTopProcessesByCpuWhenTotalTimeIsAvailable()
        {
            // ARRANGE
            TimeSpan interval          = TimeSpan.FromSeconds(2);
            var      processProvider   = new QuickPulseProcessProviderMock();
            var      baseProcessorTime = TimeSpan.FromSeconds(100);

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", baseProcessorTime),
                new QuickPulseProcess("Process2", baseProcessorTime),
                new QuickPulseProcess("Process3", baseProcessorTime),
                new QuickPulseProcess("Process4", baseProcessorTime),
                new QuickPulseProcess("Process5", baseProcessorTime)
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT

            // doesn't matter, some large value
            processProvider.OverallTimeValue = TimeSpan.FromTicks(1000 * baseProcessorTime.Ticks);
            collector.GetTopProcessesByCpu(3);

            timeProvider.FastForward(interval);

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", baseProcessorTime + TimeSpan.FromMilliseconds(50)),
                new QuickPulseProcess("Process2", baseProcessorTime + TimeSpan.FromMilliseconds(100)),
                new QuickPulseProcess("Process3", baseProcessorTime + TimeSpan.FromMilliseconds(75)),
                new QuickPulseProcess("Process4", baseProcessorTime + TimeSpan.FromMilliseconds(25)),
                new QuickPulseProcess("Process5", baseProcessorTime + TimeSpan.FromMilliseconds(125))
            };
            processProvider.OverallTimeValue += TimeSpan.FromTicks(Environment.ProcessorCount * interval.Ticks);

            var topProcesses = collector.GetTopProcessesByCpu(3).ToList();

            // ASSERT
            Assert.AreEqual(3, topProcesses.Count);

            Assert.AreEqual("Process5", topProcesses[0].Item1);
            Assert.AreEqual((int)((125.0 / (Environment.ProcessorCount * interval.TotalMilliseconds)) * 100), topProcesses[0].Item2);

            Assert.AreEqual("Process2", topProcesses[1].Item1);
            Assert.AreEqual((int)((100.0 / (Environment.ProcessorCount * interval.TotalMilliseconds)) * 100), topProcesses[1].Item2);

            Assert.AreEqual("Process3", topProcesses[2].Item1);
            Assert.AreEqual((int)((75.0 / (Environment.ProcessorCount * interval.TotalMilliseconds)) * 100), topProcesses[2].Item2);
        }
コード例 #10
0
        public void QuickPulseServiceClientSubmitsTransmissionTimeToServiceWithPing()
        {
            // ARRANGE
            var timeProvider  = new ClockMock();
            var serviceClient = new QuickPulseServiceClient(this.serviceEndpoint, string.Empty, string.Empty, string.Empty, string.Empty, timeProvider, false);

            // ACT
            serviceClient.Ping(Guid.NewGuid().ToString(), timeProvider.UtcNow);

            // ASSERT
            this.listener.Stop();

            Assert.AreEqual(1, this.pings.Count);
            Assert.AreEqual(timeProvider.UtcNow.Ticks, this.pings[0].Item1.TransmissionTime.Ticks);
        }
コード例 #11
0
        public void QuickPulseTopCpuCollectorHandlesExceptionFromProcessProvider()
        {
            // ARRANGE
            var processProvider = new QuickPulseProcessProviderMock()
            {
                AlwaysThrow = new Exception()
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT
            var topProcesses = collector.GetTopProcessesByCpu(3);

            // ASSERT
            Assert.AreEqual(0, topProcesses.Count());
        }
コード例 #12
0
        public void QuickPulseTopCpuCollectorSetsInitializationStatusCorrectlyWhenSecurityExceptionIsThrown()
        {
            // ARRANGE
            var processProvider = new QuickPulseProcessProviderMock {
                AlwaysThrow = new SecurityException()
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT
            collector.Initialize();

            // ASSERT
            Assert.IsTrue(collector.InitializationFailed);
            Assert.IsTrue(collector.AccessDenied);
        }
        public void QuickPulseCollectionStateManagerDoesNothingWithoutInstrumentationKey()
        {
            // ARRANGE
            var timings = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock { ReturnValueFromPing = true, ReturnValueFromSubmitSample = true };
            var actions = new List<string>();
            var returnedSamples = new List<QuickPulseDataSample>();
            var timeProvider = new ClockMock();
            var manager = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            // ACT
            manager.UpdateState(string.Empty);
            manager.UpdateState(null);

            // ASSERT
            Assert.AreEqual(0, serviceClient.PingCount);
            Assert.AreEqual(0, serviceClient.SnappedSamples.Count);
        }
コード例 #14
0
        public void QuickPulseCollectionStateManagerDoesNothingWithoutInstrumentationKey()
        {
            // ARRANGE
            var timings       = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock {
                ReturnValueFromPing = true, ReturnValueFromSubmitSample = true
            };
            var actions         = new List <string>();
            var returnedSamples = new List <QuickPulseDataSample>();
            var timeProvider    = new ClockMock();
            var manager         = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            // ACT
            manager.UpdateState(string.Empty);
            manager.UpdateState(null);

            // ASSERT
            Assert.AreEqual(0, serviceClient.PingCount);
            Assert.AreEqual(0, serviceClient.SnappedSamples.Count);
        }
コード例 #15
0
        public void QuickPulseQuotaTrackerQuotaNotEmptyAtStart()
        {
            // ARRANGE
            int  startQuota = 10;
            bool counted;
            var  mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, 30, startQuota);

            // ACT & ASSERT
            while (startQuota > 0)
            {
                counted = quotaTracker.ApplyQuota();
                Assert.IsTrue(counted);
                --startQuota;
            }

            // Quota should be exhausted.
            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted);
        }
コード例 #16
0
        public void QuickPulseCollectionStateManagerPingBacksOffWhenConnectionInitiallyDown()
        {
            // ARRANGE
            var timings       = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock {
                ReturnValueFromPing = null, ReturnValueFromSubmitSample = null
            };
            var actions         = new List <string>();
            var returnedSamples = new List <QuickPulseDataSample>();
            var timeProvider    = new ClockMock();
            var manager         = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            // ACT & ASSERT
            manager.UpdateState("some ikey");

            timeProvider.FastForward(timings.TimeToServicePollingBackOff.Add(TimeSpan.FromSeconds(-1)));
            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState("some ikey"));

            timeProvider.FastForward(TimeSpan.FromSeconds(2));
            Assert.AreEqual(timings.ServicePollingBackedOffInterval, manager.UpdateState("some ikey"));
        }
コード例 #17
0
        public void QuickPulseTopCpuCollectorReturnsNothingWhenCalledForTheFirstTime()
        {
            // ARRANGE
            var processProvider = new QuickPulseProcessProviderMock();

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", TimeSpan.FromSeconds(50)),
                new QuickPulseProcess("Process2", TimeSpan.FromSeconds(100)),
                new QuickPulseProcess("Process3", TimeSpan.FromSeconds(75)),
                new QuickPulseProcess("Process4", TimeSpan.FromSeconds(25)),
                new QuickPulseProcess("Process5", TimeSpan.FromSeconds(125)),
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            // ACT
            var topProcesses = collector.GetTopProcessesByCpu(3).ToList();

            // ASSERT
            Assert.AreEqual(0, topProcesses.Count);
        }
        public void QuickPulseQuotaTrackerQuotaGetsRefilled()
        {
            // ARRANGE
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, 30, 0);
            bool counted;

            // ACT & ASSERT
            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // No quota yet

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1)); // 0.5 quota accumulated
            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // No quota yet

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1)); // 1 quota accumulated
            counted = quotaTracker.ApplyQuota();
            Assert.IsTrue(counted);

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // Quota was already exhausted.
        }
コード例 #19
0
        public void QuickPulseQuotaTrackerQuotaDoesNotExceedMax()
        {
            // ARRANGE
            int startQuota       = 10;
            int maxQuota         = 30;
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, startQuota);
            bool counted;

            mockTimeProvider.FastForward(TimeSpan.FromDays(1));

            // ACT & ASSERT
            while (maxQuota > 0)
            {
                counted = quotaTracker.ApplyQuota();
                Assert.IsTrue(counted);
                --maxQuota;
            }

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // We should exhaust quota by this time
        }
        public void QuickPulseQuotaTrackerQuotaDoesNotExceedMax()
        {
            // ARRANGE
            int startQuota = 10;
            int maxQuota = 30;
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, startQuota);
            bool counted;

            mockTimeProvider.FastForward(TimeSpan.FromDays(1));

            // ACT & ASSERT
            while (maxQuota > 0)
            {
                counted = quotaTracker.ApplyQuota();
                Assert.IsTrue(counted);
                --maxQuota;
            }

            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted); // We should exhaust quota by this time
        }
コード例 #21
0
        public void QuickPulseServiceClientSubmitsTransmissionTimeToServiceWithSubmitSamples()
        {
            // ARRANGE
            var timeProvider  = new ClockMock();
            var serviceClient = new QuickPulseServiceClient(this.serviceEndpoint, string.Empty, string.Empty, string.Empty, string.Empty, timeProvider, false);
            var sample        = new QuickPulseDataSample(
                new QuickPulseDataAccumulator {
                StartTimestamp = timeProvider.UtcNow, EndTimestamp = timeProvider.UtcNow.AddSeconds(1)
            },
                new Dictionary <string, Tuple <PerformanceCounterData, double> >(),
                Enumerable.Empty <Tuple <string, int> >(),
                false);

            // ACT
            serviceClient.SubmitSamples(new[] { sample }, string.Empty);

            // ASSERT
            this.listener.Stop();

            Assert.AreEqual(1, this.samples.Count);
            Assert.AreEqual(timeProvider.UtcNow.Ticks, this.samples[0].Item1.Ticks);
        }
コード例 #22
0
        public void QuickPulseTopCpuCollectorCleansUpStateWhenProcessesGoAway()
        {
            // ARRANGE
            var processProvider   = new QuickPulseProcessProviderMock();
            var baseProcessorTime = TimeSpan.FromSeconds(100);

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", baseProcessorTime),
                new QuickPulseProcess("Process2", baseProcessorTime),
                new QuickPulseProcess("Process3", baseProcessorTime),
                new QuickPulseProcess("Process4", baseProcessorTime),
                new QuickPulseProcess("Process5", baseProcessorTime),
            };
            var timeProvider = new ClockMock();
            var collector    = new QuickPulseTopCpuCollector(timeProvider, processProvider);

            var processDictionary =
                QuickPulseTestHelper.GetPrivateField(collector, "processObservations") as Dictionary <string, TimeSpan>;

            // ACT
            collector.GetTopProcessesByCpu(3);
            int itemCount1 = processDictionary.Count;

            timeProvider.FastForward(TimeSpan.FromSeconds(1));

            processProvider.Processes = new List <QuickPulseProcess>()
            {
                new QuickPulseProcess("Process1", baseProcessorTime)
            };
            collector.GetTopProcessesByCpu(3);
            int itemCount3 = processDictionary.Count;

            // ASSERT
            Assert.AreEqual(5, itemCount1);
            Assert.AreEqual(1, itemCount3);
        }
コード例 #23
0
        public void QuickPulseQuotaTrackerIsThreadSafe()
        {
            // ARRANGE
            int maxQuota = 100 * 60;
            int experimentLengthInSeconds = 1000;
            int concurrency = 1000;

            var mockTimeProvider = new ClockMock();
            var quotaTracker     = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, 0);

            var quotaApplicationResults = new ConcurrentQueue <bool>();

            // ACT
            for (int i = 0; i < experimentLengthInSeconds; i++)
            {
                mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));

                var tasks = new List <Action>();
                for (int j = 0; j < concurrency; j++)
                {
                    tasks.Add(() => quotaApplicationResults.Enqueue(quotaTracker.ApplyQuota()));
                }

                Parallel.Invoke(new ParallelOptions()
                {
                    MaxDegreeOfParallelism = concurrency
                }, tasks.ToArray());
            }

            // ASSERT
            var passedQuotaCount = quotaApplicationResults.Count(result => result);
            var correctResult    = maxQuota / 60 * experimentLengthInSeconds;

            Assert.AreEqual(correctResult, passedQuotaCount);
            Assert.IsFalse(quotaTracker.ApplyQuota());
        }
        public void QuickPulseTelemetryProcessorDoesNotCollectFullExceptionTelemetryItemsOnceQuotaIsExhausted()
        {
            // ARRANGE
            var accumulatorManager = new QuickPulseDataAccumulatorManager();
            var timeProvider = new ClockMock();
            var telemetryProcessor = new QuickPulseTelemetryProcessor(new SimpleTelemetryProcessorSpy(), timeProvider, 60, 5);
            var instrumentationKey = "some ikey";
            ((IQuickPulseTelemetryProcessor)telemetryProcessor).StartCollection(
                accumulatorManager,
                new Uri("http://microsoft.com"),
                new TelemetryConfiguration() { InstrumentationKey = instrumentationKey });

            // ACT
            int counter = 0;
            for (int i = 0; i < 100; i++)
            {
                var exception = new ExceptionTelemetry(new Exception((counter++).ToString(CultureInfo.InvariantCulture)))
                                    {
                                        Context = { InstrumentationKey = instrumentationKey }
                                    };

                telemetryProcessor.Process(exception);
            }

            timeProvider.FastForward(TimeSpan.FromSeconds(30));

            for (int i = 0; i < 100; i++)
            {
                var exception = new ExceptionTelemetry(new Exception((counter++).ToString(CultureInfo.InvariantCulture)))
                                    {
                                        Context = { InstrumentationKey = instrumentationKey }
                                    };

                telemetryProcessor.Process(exception);
            }

            // ASSERT
            var collectedTelemetry = accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.ToArray().Reverse().Cast<ExceptionTelemetryDocument>().ToArray();

            Assert.AreEqual(5 + 30, accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.Count);

            // out of the first 100 items we expect to see items 0 through 4 (the initial quota)
            for (int i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, int.Parse(collectedTelemetry[i].ExceptionMessage, CultureInfo.InvariantCulture));
            }

            // out of the second 100 items we expect to see items 100 through 129 (the new quota for 30 seconds)
            for (int i = 5; i < 35; i++)
            {
                Assert.AreEqual(95 + i, int.Parse(collectedTelemetry[i].ExceptionMessage, CultureInfo.InvariantCulture));
            }
        }
        public void QuickPulseQuotaTrackerQuotaNotEmptyAtStart()
        {
            // ARRANGE
            int startQuota = 10;
            bool counted;
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, 30, startQuota);

            // ACT & ASSERT
            while (startQuota > 0)
            {
                counted = quotaTracker.ApplyQuota();
                Assert.IsTrue(counted);
                --startQuota;
            }

            // Quota should be exhausted.
            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted);
        }
コード例 #26
0
        public void CollectionConfigurationCarriesOverQuotaWhenCreatingDocumentStreams()
        {
            // ARRANGE
            var timeProvider = new ClockMock();

            CollectionConfigurationError[] errors;
            var oldDocumentStreamInfos = new[]
            {
                new DocumentStreamInfo()
                {
                    Id = "Stream1",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Request,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream2",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Dependency,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream3",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Exception,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                }
            };

            var newDocumentStreamInfos = new[]
            {
                new DocumentStreamInfo()
                {
                    Id = "Stream1",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Request,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream2",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Dependency,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream3",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Exception,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream4",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Event,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                },
                new DocumentStreamInfo()
                {
                    Id = "Stream5",
                    DocumentFilterGroups =
                        new[]
                    {
                        new DocumentFilterConjunctionGroupInfo()
                        {
                            TelemetryType = TelemetryType.Trace,
                            Filters       = new FilterConjunctionGroupInfo()
                            {
                                Filters = new FilterInfo[0]
                            }
                        }
                    }
                }
            };

            var oldCollectionConfigurationInfo = new CollectionConfigurationInfo()
            {
                DocumentStreams = oldDocumentStreamInfos, ETag = "ETag1"
            };
            var oldCollectionConfiguration = new CollectionConfiguration(oldCollectionConfigurationInfo, out errors, timeProvider);

            // spend some quota on the old configuration
            var accumulatorManager = new QuickPulseDataAccumulatorManager(oldCollectionConfiguration);
            var telemetryProcessor = new QuickPulseTelemetryProcessor(new SimpleTelemetryProcessorSpy());

            ((IQuickPulseTelemetryProcessor)telemetryProcessor).StartCollection(
                accumulatorManager,
                new Uri("http://microsoft.com"),
                new TelemetryConfiguration()
            {
                InstrumentationKey = "some ikey"
            });

            // ACT
            // the initial quota is 3
            telemetryProcessor.Process(new RequestTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });

            telemetryProcessor.Process(new DependencyTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });
            telemetryProcessor.Process(new DependencyTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });

            telemetryProcessor.Process(new ExceptionTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });
            telemetryProcessor.Process(new ExceptionTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });
            telemetryProcessor.Process(new ExceptionTelemetry()
            {
                Context = { InstrumentationKey = "some ikey" }
            });

            // ACT
            // the new configuration must carry the quotas over from the old one (only for those document streams that already existed)
            var newCollectionConfigurationInfo = new CollectionConfigurationInfo()
            {
                DocumentStreams = newDocumentStreamInfos, ETag = "ETag1"
            };
            var newCollectionConfiguration = new CollectionConfiguration(
                newCollectionConfigurationInfo,
                out errors,
                timeProvider,
                oldCollectionConfiguration.DocumentStreams);

            // ASSERT
            DocumentStream[] documentStreams = newCollectionConfiguration.DocumentStreams.ToArray();
            Assert.AreEqual(5, documentStreams.Length);

            Assert.AreEqual("Stream1", documentStreams[0].Id);
            Assert.AreEqual(2, documentStreams[0].RequestQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[0].DependencyQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[0].ExceptionQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[0].EventQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[0].EventQuotaTracker.CurrentQuota);

            Assert.AreEqual("Stream2", documentStreams[1].Id);
            Assert.AreEqual(3, documentStreams[1].RequestQuotaTracker.CurrentQuota);
            Assert.AreEqual(1, documentStreams[1].DependencyQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[1].ExceptionQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[1].EventQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[1].EventQuotaTracker.CurrentQuota);

            Assert.AreEqual("Stream3", documentStreams[2].Id);
            Assert.AreEqual(3, documentStreams[2].RequestQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[2].DependencyQuotaTracker.CurrentQuota);
            Assert.AreEqual(0, documentStreams[2].ExceptionQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[2].EventQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[2].EventQuotaTracker.CurrentQuota);

            Assert.AreEqual("Stream4", documentStreams[3].Id);
            Assert.AreEqual(3, documentStreams[3].RequestQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[3].DependencyQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[3].ExceptionQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[3].EventQuotaTracker.CurrentQuota);
            Assert.AreEqual(3, documentStreams[3].EventQuotaTracker.CurrentQuota);
        }
        public void QuickPulseTelemetryProcessorDoesNotCollectFullRequestTelemetryItemsOnceQuotaIsExhausted()
        {
            // ARRANGE
            var accumulatorManager = new QuickPulseDataAccumulatorManager();
            var timeProvider = new ClockMock();
            var telemetryProcessor = new QuickPulseTelemetryProcessor(new SimpleTelemetryProcessorSpy(), timeProvider, 60, 5);
            var instrumentationKey = "some ikey";
            ((IQuickPulseTelemetryProcessor)telemetryProcessor).StartCollection(
                accumulatorManager,
                new Uri("http://microsoft.com"),
                new TelemetryConfiguration() { InstrumentationKey = instrumentationKey });

            // ACT
            int counter = 0;
            for (int i = 0; i < 100; i++)
            {
                var request = new RequestTelemetry()
                                  {
                                      Success = false,
                                      ResponseCode = "400",
                                      Duration = TimeSpan.FromSeconds(counter++),
                                      Context = { InstrumentationKey = instrumentationKey }
                                  };

                telemetryProcessor.Process(request);
            }

            timeProvider.FastForward(TimeSpan.FromSeconds(30));

            for (int i = 0; i < 100; i++)
            {
                var request = new RequestTelemetry()
                {
                    Success = false,
                    ResponseCode = "400",
                    Duration = TimeSpan.FromSeconds(counter++),
                    Context = { InstrumentationKey = instrumentationKey }
                };

                telemetryProcessor.Process(request);
            }

            // ASSERT
            var collectedTelemetry = accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.ToArray().Reverse().Cast<RequestTelemetryDocument>().ToArray();

            Assert.AreEqual(5 + 30, accumulatorManager.CurrentDataAccumulator.TelemetryDocuments.Count);

            // out of the first 100 items we expect to see items 0 through 4 (the initial quota)
            for (int i = 0; i < 5; i++)
            {
                Assert.AreEqual(i, collectedTelemetry[i].Duration.TotalSeconds);
            }

            // out of the second 100 items we expect to see items 100 through 129 (the new quota for 30 seconds)
            for (int i = 5; i < 35; i++)
            {
                Assert.AreEqual(95 + i, collectedTelemetry[i].Duration.TotalSeconds);
            }
        }
        public void QuickPulseServiceClientSetsTransmissionTimeCorrectly()
        {
            // ARRANGE
            var dummy = new Dictionary<string, Tuple<PerformanceCounterData, float>>();
            var timeProvider = new ClockMock();

            var serviceClient = new QuickPulseServiceClient(this.serviceEndpoint, string.Empty, string.Empty, timeProvider);
            var sample1 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator { StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow },
                    dummy);

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            var sample2 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator { StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow },
                    dummy);

            timeProvider.FastForward(TimeSpan.FromSeconds(1));
            var sample3 =
                new QuickPulseDataSample(
                    new QuickPulseDataAccumulator { StartTimestamp = timeProvider.UtcNow.AddSeconds(-1), EndTimestamp = timeProvider.UtcNow },
                    dummy);

            // ACT
            timeProvider.FastForward(TimeSpan.FromSeconds(5));
            serviceClient.SubmitSamples(new[] { sample1, sample2, sample3 }, string.Empty);

            // ASSERT
            this.listener.Stop();

            Assert.AreEqual(3, this.samples.Count);
            Assert.IsTrue((timeProvider.UtcNow - this.samples[0].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue((timeProvider.UtcNow - this.samples[1].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue((timeProvider.UtcNow - this.samples[2].Item1).Duration() < TimeSpan.FromMilliseconds(1));
            Assert.IsTrue(this.samples.All(s => (s.Item2.Timestamp - timeProvider.UtcNow).Duration() > TimeSpan.FromSeconds(1)));
        }
        public void QuickPulseQuotaTrackerShouldNotGetBursts()
        {
            // ARRANGE
            int maxQuota = 30;
            var mockTimeProvider = new ClockMock();
            QuickPulseQuotaTracker quotaTracker = new QuickPulseQuotaTracker(mockTimeProvider, maxQuota, 0);

            mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));

            // ACT & ASSERT
            // Emulate that every second we try to track 100 of documents. We should expect
            // only one document every 2nd second (quota = 30 documents per min).
            for (int i = 0; i < 1000; i++)
            {
                int count = 0;
                for (int j = 0; j < 100; j++)
                {
                    bool counted = quotaTracker.ApplyQuota();
                    if (counted)
                    {
                        ++count;
                    }
                }

                Assert.AreEqual((i % 2) == 0 ? 0 : 1, count);

                mockTimeProvider.FastForward(TimeSpan.FromSeconds(1));
            }
        }
        public void QuickPulseCollectionStateManagerSubmitBacksOffWhenConnectionInitiallyDown()
        {
            // ARRANGE
            var timings = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock { ReturnValueFromPing = true, ReturnValueFromSubmitSample = null };
            var actions = new List<string>();
            var returnedSamples = new List<QuickPulseDataSample>();
            var timeProvider = new ClockMock();
            var manager = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            // ACT & ASSERT
            Assert.AreEqual(timings.CollectionInterval, manager.UpdateState("some ikey"));
            Assert.IsTrue(manager.IsCollectingData);

            timeProvider.FastForward(timings.TimeToCollectionBackOff.Add(TimeSpan.FromSeconds(-1)));
            Assert.AreEqual(timings.CollectionInterval, manager.UpdateState("some ikey"));
            Assert.IsTrue(manager.IsCollectingData);

            timeProvider.FastForward(TimeSpan.FromSeconds(2));
            Assert.AreEqual(timings.ServicePollingBackedOffInterval, manager.UpdateState("some ikey"));
            Assert.AreEqual(false, manager.IsCollectingData);
        }
        public void QuickPulseCollectionStateManagerPingRecovers()
        {
            // ARRANGE
            var timings = QuickPulseTimings.Default;
            var serviceClient = new QuickPulseServiceClientMock { ReturnValueFromPing = false, ReturnValueFromSubmitSample = false };
            var actions = new List<string>();
            var returnedSamples = new List<QuickPulseDataSample>();
            var timeProvider = new ClockMock();
            var manager = CreateManager(serviceClient, timeProvider, actions, returnedSamples, timings);

            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState(string.Empty));

            // ACT
            serviceClient.ReturnValueFromPing = null;
            timeProvider.FastForward(timings.TimeToServicePollingBackOff.Add(TimeSpan.FromSeconds(1)));
            manager.UpdateState(string.Empty);

            timeProvider.FastForward(TimeSpan.FromMinutes(1));
            serviceClient.ReturnValueFromPing = false;

            // ASSERT
            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState(string.Empty));
        }