public void CounterAggregatorMergesCaseInsenstively() { var aggregator = new CounterAggregator(DefaultDimensions); var now = DateTime.Now; aggregator.AddMachineResponse(this.CreateResponse(now, 1, 0, 1, 1, "taco")); aggregator.AddMachineResponse(this.CreateResponse(now, 1, 0, 1, 1, "TACO")); Assert.AreEqual(1, aggregator.Samples.Count()); }
public void CounterAggregatorCanHandleRangesWhichDoNotOverlap() { var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 5)); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now.AddDays(-1), 1, 1, 5)); Assert.AreEqual(10, aggregator.Samples.Count(item => { this.VerifySample(item, 1); return(true); })); }
public void CounterAggregatorCanHandleSupersetRange() { var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 9)); // super bucket aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now.AddHours(-1), 600, 10, 1)); Assert.AreEqual(1, aggregator.Samples.Count(item => { this.VerifySample(item, 10); return(true); })); }
public void CounterAggregatorRejectsPerMachinePercentiles() { var aggregator = new CounterAggregator(DefaultDimensions); var response = new CounterQueryResponse { HttpResponseCode = 200, Samples = new List <DataSample> { new DataSample { Name = "bob", StartTime = DateTime.Now.ToMillisecondTimestamp(), EndTime = DateTime.Now.ToMillisecondTimestamp(), Dimensions = new Dictionary <string, string> { { AnyDimensionName, "tacos" } }, SampleType = DataSampleType.Percentile, Percentile = 40, PercentileValue = 11, } } }; Assert.Throws <ArgumentException>(() => aggregator.AddMachineResponse(response)); }
public void CounterAggregatorCanSmashAllBucketsTogether() { var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 10)); var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); this.VerifySample(superSamples.First(), 10); Assert.AreEqual(1, superSamples.Count()); }
/// <summary> /// Merge the local Query request and the distributed tiered response into a single response /// </summary> private static CounterQueryResponse MergeResponses(IDictionary <string, string> queryParameters, CounterQueryResponse localResponse, bool mergeTimeBuckets, CounterQueryResponse distributedResponse) { // no distributed response, just use the local one if (distributedResponse == null) { return(localResponse); } var sampleMerger = new CounterAggregator(queryParameters ?? new Dictionary <string, string>(0)); sampleMerger.AddMachineResponse(localResponse); sampleMerger.AddMachineResponse(distributedResponse); // response code from this server is: // 200: *Anyone* has data // 40X: *Everyone failed to get data, but everyone has the same response code // 409: Mixed error codes ("Conflict" used liberally) HttpStatusCode responseCode; if ((localResponse.Samples != null && localResponse.Samples.Count > 0) || (distributedResponse.Samples != null && distributedResponse.Samples.Count > 0)) { responseCode = HttpStatusCode.OK; } else { responseCode = distributedResponse.RequestDetails != null && distributedResponse.RequestDetails.Count > 0 && distributedResponse.RequestDetails.All(d => d.HttpResponseCode == (int)localResponse.HttpResponseCode) ? (HttpStatusCode)localResponse.HttpResponseCode : HttpStatusCode.Conflict; } var mergedResponse = sampleMerger.GetResponse(mergeTimeBuckets); mergedResponse.HttpResponseCode = (short)responseCode; return(mergedResponse); }
public void CounterAggregatorCanHandleRangesWhichAlwaysOverlap() { var aggregator = new CounterAggregator(DefaultDimensions); // 10 minute buckets, staggered by 2 minute increments. Should 100% overlap aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 10, 2, 10)); Assert.AreEqual(1, aggregator.Samples.Count(item => { this.VerifySample(item, 10); return(true); })); }
public void CounterAggregatorCountsMachinesCorrectly() { var aggregator = new CounterAggregator(DefaultDimensions); var response = this.CreateResponse(DateTime.Now, 1, 1, 10); const int MachineCount = 15; for (int i = 0; i < MachineCount; i++) { aggregator.AddMachineResponse(response); } var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); Assert.AreEqual(1, superSamples.Count()); Assert.AreEqual(MachineCount, (int)superSamples.First().MachineCount); }
public void CounterAggregatorKeepsDifferentSamplesSeparate() { // this ensures split by works correctly var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 10, 5)); var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); Assert.AreEqual(5, superSamples.Count()); superSamples.All(x => { this.VerifySample(x, 10); return(true); }); }
public void CounterAggregatorCalculatesPercentileAfterAggregation() { var aggregator = new CounterAggregator(DefaultDimensions); var response = new CounterQueryResponse { HttpResponseCode = 200, Samples = new List <DataSample> { new DataSample { Name = "bob", StartTime = DateTime.Now.ToMillisecondTimestamp(), EndTime = DateTime.Now.ToMillisecondTimestamp(), Dimensions = new Dictionary <string, string> { { AnyDimensionName, "tacos" } }, SampleType = DataSampleType.Histogram, Histogram = new Dictionary <long, uint> { { 1, 1 }, { 2, 1 }, { 3, 1 }, { 4, 1 }, { 5, 1 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 10, 1 } } } } }; // by default, we do not apply percentile filtering aggregator.AddMachineResponse(response); var defaultValue = aggregator.Samples.First(); Assert.AreEqual(DataSampleType.Histogram, defaultValue.SampleType); // now that the client asked for filtering, we calculate the 99.999% percentile (should be the max value from earlier) aggregator.ApplyPercentileCalculationAggregation(new Dictionary <string, string> { { "Percentile", "99.999" } }); var aggregatedValue = aggregator.Samples.First(); Assert.AreEqual(DataSampleType.Percentile, aggregatedValue.SampleType); Assert.AreEqual(10, aggregatedValue.PercentileValue); }
public void CounterAggregatorRollsUpMachineCountProperly() { var aggregator = new CounterAggregator(DefaultDimensions); var response = this.CreateResponse(DateTime.Now, 1, 1, 10); const int ResponseCount = 15; const int MachineCountPerResponse = 10; // add multiple machines per response response.Samples = response.Samples.Select(s => { var originalValue = s; return(new DataSample { Dimensions = originalValue.Dimensions, EndTime = originalValue.EndTime, HitCount = originalValue.HitCount, MachineCount = MachineCountPerResponse, Name = originalValue.Name, SampleType = originalValue.SampleType, StartTime = originalValue.StartTime }); }).ToList(); for (int i = 0; i < ResponseCount; i++) { aggregator.AddMachineResponse(response); } var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); Assert.AreEqual(1, superSamples.Count()); Assert.AreEqual(MachineCountPerResponse * ResponseCount, (int)superSamples.First().MachineCount); }
public void CounterAggregatorKeepsDifferentSamplesSeparate() { // this ensures split by works correctly var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 10, 5)); var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); Assert.AreEqual(5, superSamples.Count()); superSamples.All(x => { this.VerifySample(x, 10); return true; }); }
public void CounterAggregatorCalculatesPercentileAfterAggregation() { var aggregator = new CounterAggregator(DefaultDimensions); var response = new CounterQueryResponse { HttpResponseCode = 200, Samples = new List<DataSample> { new DataSample { Name = "bob", StartTime = DateTime.Now.ToMillisecondTimestamp(), EndTime = DateTime.Now.ToMillisecondTimestamp(), Dimensions = new Dictionary<string, string> {{AnyDimensionName, "tacos"}}, SampleType = DataSampleType.Histogram, Histogram = new Dictionary<long, uint> {{1,1},{2,1},{3,1},{4,1},{5,1},{6,1},{7,1},{8,1},{9,1},{10,1}} } } }; // by default, we do not apply percentile filtering aggregator.AddMachineResponse(response); var defaultValue = aggregator.Samples.First(); Assert.AreEqual(DataSampleType.Histogram, defaultValue.SampleType); // now that the client asked for filtering, we calculate the 99.999% percentile (should be the max value from earlier) aggregator.ApplyPercentileCalculationAggregation(new Dictionary<string, string> {{"Percentile", "99.999"}}); var aggregatedValue = aggregator.Samples.First(); Assert.AreEqual(DataSampleType.Percentile, aggregatedValue.SampleType); Assert.AreEqual(10, aggregatedValue.PercentileValue); }
public void CounterAggregatorRejectsPerMachinePercentiles() { var aggregator = new CounterAggregator(DefaultDimensions); var response = new CounterQueryResponse { HttpResponseCode = 200, Samples = new List<DataSample> { new DataSample { Name = "bob", StartTime = DateTime.Now.ToMillisecondTimestamp(), EndTime = DateTime.Now.ToMillisecondTimestamp(), Dimensions = new Dictionary<string, string> {{AnyDimensionName, "tacos"}}, SampleType = DataSampleType.Percentile, Percentile = 40, PercentileValue = 11, } } }; Assert.Throws<ArgumentException>(() => aggregator.AddMachineResponse(response)); }
public void CounterAggregatorCanHandleRangesWhichAlwaysOverlap() { var aggregator = new CounterAggregator(DefaultDimensions); // 10 minute buckets, staggered by 2 minute increments. Should 100% overlap aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 10, 2, 10)); Assert.AreEqual(1, aggregator.Samples.Count(item => { this.VerifySample(item, 10); return true; })); }
public void CounterAggregatorCanHandleSupersetRange() { var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 9)); // super bucket aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now.AddHours(-1), 600, 10, 1)); Assert.AreEqual(1, aggregator.Samples.Count(item => { this.VerifySample(item, 10); return true; })); }
public void CounterAggregatorRollsUpMachineCountProperly() { var aggregator = new CounterAggregator(DefaultDimensions); var response = this.CreateResponse(DateTime.Now, 1, 1, 10); const int ResponseCount = 15; const int MachineCountPerResponse = 10; // add multiple machines per response response.Samples = response.Samples.Select(s => { var originalValue = s; return new DataSample { Dimensions = originalValue.Dimensions, EndTime = originalValue.EndTime, HitCount = originalValue.HitCount, MachineCount = MachineCountPerResponse, Name = originalValue.Name, SampleType = originalValue.SampleType, StartTime = originalValue.StartTime }; }).ToList(); for (int i = 0; i < ResponseCount; i++) { aggregator.AddMachineResponse(response); } var superSamples = aggregator.TimeMergedSamples; Assert.IsNotNull(superSamples); Assert.AreEqual(1, superSamples.Count()); Assert.AreEqual(MachineCountPerResponse * ResponseCount, (int)superSamples.First().MachineCount); }
public void CounterAggregatorCanHandleRangesWhichDoNotOverlap() { var aggregator = new CounterAggregator(DefaultDimensions); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now, 1, 1, 5)); aggregator.AddMachineResponse(this.CreateResponse(DateTime.Now.AddDays(-1), 1, 1, 5)); Assert.AreEqual(10, aggregator.Samples.Count(item => { this.VerifySample(item, 1); return true; })); }