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, string.Empty);

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

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

            timeProvider.FastForward(TimeSpan.FromSeconds(2));
            Assert.AreEqual(timings.ServicePollingBackedOffInterval, manager.UpdateState("some ikey", string.Empty));
            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, string.Empty));

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

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

            // ASSERT
            Assert.AreEqual(timings.ServicePollingInterval, manager.UpdateState(string.Empty, string.Empty));
        }
        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());
        }
Exemplo n.º 4
0
        public void QuickPulseCollectionStateManagerRespectsServicePollingIntervalHint()
        {
            // 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);
            TimeSpan intervalHint1   = TimeSpan.FromSeconds(65);
            TimeSpan intervalHint2   = TimeSpan.FromSeconds(75);

            // ACT
            serviceClient.ReturnValueFromPing = false;

            TimeSpan oldServicePollingInterval = manager.UpdateState("ikey1", string.Empty);

            serviceClient.ServicePollingIntervalHint = intervalHint1;
            TimeSpan newServicePollingInterval1 = manager.UpdateState("ikey1", string.Empty);

            serviceClient.ServicePollingIntervalHint = intervalHint2;
            TimeSpan newServicePollingInterval2 = manager.UpdateState("ikey1", string.Empty);

            serviceClient.ServicePollingIntervalHint = null;
            TimeSpan newServicePollingInterval3 = manager.UpdateState("ikey1", string.Empty);

            // ASSERT
            Assert.AreEqual(timings.ServicePollingInterval, oldServicePollingInterval);
            Assert.AreEqual(intervalHint1, newServicePollingInterval1);
            Assert.AreEqual(intervalHint2, newServicePollingInterval2);
            Assert.AreEqual(intervalHint2, newServicePollingInterval3);
        }
Exemplo n.º 5
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));
            }
        }
Exemplo n.º 6
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);
        }
        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);

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

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

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

            // ASSERT
            Assert.AreEqual(5, itemCount1);
            Assert.AreEqual(1, itemCount3);
        }
        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);
        }
        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);
        }
        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 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());
        }
        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, string.Empty);
            manager.UpdateState(null, string.Empty);

            // ASSERT
            Assert.AreEqual(0, serviceClient.PingCount);
            Assert.AreEqual(0, serviceClient.SnappedSamples.Count);
        }
Exemplo n.º 13
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 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);
        }
Exemplo n.º 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)
            {
                Assert.IsFalse(quotaTracker.QuotaExhausted);
                counted = quotaTracker.ApplyQuota();
                Assert.IsTrue(counted);
                --startQuota;
            }

            // Quota should be exhausted.
            counted = quotaTracker.ApplyQuota();
            Assert.IsFalse(counted);
            Assert.AreEqual(0f, quotaTracker.CurrentQuota);
            Assert.IsTrue(quotaTracker.QuotaExhausted);
        }
Exemplo n.º 16
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 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);
        }