public void sql_traces_are_retained_after_harvest_if_response_equals_retain()
        {
            // Arrange
            var sentSqlTracesCount = int.MinValue;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .Returns <IEnumerable <SqlTraceWireModel> >(sqlTraces =>
            {
                sentSqlTracesCount = sqlTraces.Count();
                return(DataTransportResponseStatus.Retain);
            });

            var sqlTracesToSend = new SqlTraceStatsCollection();

            sqlTracesToSend.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(10)));
            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();
            sentSqlTracesCount = int.MinValue; // reset
            _harvestAction();

            // Assert
            Assert.AreEqual(1, sentSqlTracesCount);
        }
 public void Merge(SqlTraceStatsCollection newTraces)
 {
     foreach (var item in newTraces.Collection)
     {
         Insert(item.Value);
     }
 }
        public void zero_sql_traces_are_retained_after_harvest_if_response_equals_post_too_big_error()
        {
            // Arrange
            IEnumerable <SqlTraceWireModel> sentSqlTraces = null;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .Returns <IEnumerable <SqlTraceWireModel> >(sqlTraces =>
            {
                sentSqlTraces = sqlTraces;
                return(DataTransportResponseStatus.ReduceSizeIfPossibleOtherwiseDiscard);
            });

            var sqlTracesToSend = new SqlTraceStatsCollection();

            sqlTracesToSend.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(10)));
            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();
            sentSqlTraces = null; // reset
            _harvestAction();

            // Assert
            Assert.Null(sentSqlTraces);
        }
        public void send_slowest_traces_multiple_collections_longest_aggregates_first()
        {
            // Arrange
            var sqlTracesPerPeriod = 5;
            var configuration      = GetDefaultConfiguration(int.MaxValue, sqlTracesPerPeriod);

            EventBus <ConfigurationUpdatedEvent> .Publish(new ConfigurationUpdatedEvent(configuration, ConfigurationUpdateSource.Local));

            var sentSqlTraces = null as IEnumerable <SqlTraceWireModel>;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .DoInstead <IEnumerable <SqlTraceWireModel> >(sqlTraces => sentSqlTraces = sqlTraces);

            var sqlTracesToSend = new SqlTraceStatsCollection(maxTraces: 5);

            sqlTracesToSend.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(30)));
            sqlTracesToSend.Insert(GetSqlTrace(2, maxCallTime: TimeSpan.FromSeconds(31)));
            sqlTracesToSend.Insert(GetSqlTrace(3, maxCallTime: TimeSpan.FromSeconds(32)));
            sqlTracesToSend.Insert(GetSqlTrace(4, maxCallTime: TimeSpan.FromSeconds(33)));
            sqlTracesToSend.Insert(GetSqlTrace(5, maxCallTime: TimeSpan.FromSeconds(47)));  // longest aggregate
            sqlTracesToSend.Insert(GetSqlTrace(6, maxCallTime: TimeSpan.FromSeconds(46)));  // longest aggregate

            _sqlTraceAggregator.Collect(sqlTracesToSend);

            sqlTracesToSend.Insert(GetSqlTrace(10, maxCallTime: TimeSpan.FromSeconds(49)));
            sqlTracesToSend.Insert(GetSqlTrace(11, maxCallTime: TimeSpan.FromSeconds(25)));
            sqlTracesToSend.Insert(GetSqlTrace(12, maxCallTime: TimeSpan.FromSeconds(48)));
            sqlTracesToSend.Insert(GetSqlTrace(13, maxCallTime: TimeSpan.FromSeconds(32)));
            sqlTracesToSend.Insert(GetSqlTrace(5, maxCallTime: TimeSpan.FromSeconds(34)));  // shorter aggregate
            sqlTracesToSend.Insert(GetSqlTrace(6, maxCallTime: TimeSpan.FromSeconds(35)));  // shorter aggregate

            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();

            // Assert
            NrAssert.Multiple(
                () => Assert.AreEqual(sqlTracesPerPeriod, sentSqlTraces.Count()),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 10)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 12)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 5)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 6)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 4))
                );
        }
        public void slowest_traces_retained_when_random_order_and_aggregation()
        {
            // Arrange
            var sqlTracesPerPeriod = 5;
            var configuration      = GetDefaultConfiguration(int.MaxValue, sqlTracesPerPeriod);

            EventBus <ConfigurationUpdatedEvent> .Publish(new ConfigurationUpdatedEvent(configuration, ConfigurationUpdateSource.Local));

            var sentSqlTraces = null as IEnumerable <SqlTraceWireModel>;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .DoInstead <IEnumerable <SqlTraceWireModel> >(sqlTraces => sentSqlTraces = sqlTraces);

            var sqlTracesToSend = new SqlTraceStatsCollection(maxTraces: 10);

            sqlTracesToSend.Insert(GetSqlTrace(5, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(10)));
            sqlTracesToSend.Insert(GetSqlTrace(4, maxCallTime: TimeSpan.FromSeconds(40)));  // aggregate
            sqlTracesToSend.Insert(GetSqlTrace(3, maxCallTime: TimeSpan.FromSeconds(30)));
            sqlTracesToSend.Insert(GetSqlTrace(8, maxCallTime: TimeSpan.FromSeconds(35)));
            sqlTracesToSend.Insert(GetSqlTrace(9, maxCallTime: TimeSpan.FromSeconds(45)));
            sqlTracesToSend.Insert(GetSqlTrace(10, maxCallTime: TimeSpan.FromSeconds(33)));
            sqlTracesToSend.Insert(GetSqlTrace(11, maxCallTime: TimeSpan.FromSeconds(34)));
            sqlTracesToSend.Insert(GetSqlTrace(6, maxCallTime: TimeSpan.FromSeconds(60)));
            sqlTracesToSend.Insert(GetSqlTrace(4, maxCallTime: TimeSpan.FromSeconds(51)));  // aggregate
            sqlTracesToSend.Insert(GetSqlTrace(7, maxCallTime: TimeSpan.FromSeconds(70)));
            sqlTracesToSend.Insert(GetSqlTrace(2, maxCallTime: TimeSpan.FromSeconds(999))); // beyond max limit

            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();

            // Assert
            NrAssert.Multiple(
                () => Assert.AreEqual(sqlTracesPerPeriod, sentSqlTraces.Count()),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 2)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 4)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 5)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 6)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 7))
                );
        }
        public void concurrent_dictionary_limits_maxTraces()
        {
            var maxTraces  = 10;
            var sqlTrStats = new SqlTraceStatsCollection(maxTraces);

            sqlTrStats.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(10)));
            sqlTrStats.Insert(GetSqlTrace(2, maxCallTime: TimeSpan.FromSeconds(20)));
            sqlTrStats.Insert(GetSqlTrace(3, maxCallTime: TimeSpan.FromSeconds(30)));
            sqlTrStats.Insert(GetSqlTrace(4, maxCallTime: TimeSpan.FromSeconds(40)));
            sqlTrStats.Insert(GetSqlTrace(5, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTrStats.Insert(GetSqlTrace(6, maxCallTime: TimeSpan.FromSeconds(60)));
            sqlTrStats.Insert(GetSqlTrace(7, maxCallTime: TimeSpan.FromSeconds(70)));
            sqlTrStats.Insert(GetSqlTrace(8, maxCallTime: TimeSpan.FromSeconds(80)));
            sqlTrStats.Insert(GetSqlTrace(9, maxCallTime: TimeSpan.FromSeconds(90)));
            sqlTrStats.Insert(GetSqlTrace(10, maxCallTime: TimeSpan.FromSeconds(100)));
            sqlTrStats.Insert(GetSqlTrace(11, maxCallTime: TimeSpan.FromSeconds(110)));

            Assert.AreEqual(maxTraces, sqlTrStats.Collection.Count);
        }
        public void sql_traces_send_on_harvest()
        {
            // Arrange
            var sentSqlTraces = null as IEnumerable <SqlTraceWireModel>;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .DoInstead <IEnumerable <SqlTraceWireModel> >(sqlTraces => sentSqlTraces = sqlTraces);

            var sqlTracesToSend = new SqlTraceStatsCollection();

            sqlTracesToSend.Insert(GetSqlTrace(1));
            sqlTracesToSend.Insert(GetSqlTrace(2));
            sqlTracesToSend.Insert(GetSqlTrace(3));
            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();

            // Assert
            Assert.AreEqual(3, sentSqlTraces.Count());
            Assert.AreEqual(sentSqlTraces, sqlTracesToSend.Collection.Values.ToList());
        }
        public void all_traces_same_duration_send_last_detected()
        {
            // Arrange
            var sqlTracesPerPeriod = 5;
            var configuration      = GetDefaultConfiguration(int.MaxValue, sqlTracesPerPeriod);

            EventBus <ConfigurationUpdatedEvent> .Publish(new ConfigurationUpdatedEvent(configuration, ConfigurationUpdateSource.Local));

            var sentSqlTraces = null as IEnumerable <SqlTraceWireModel>;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .DoInstead <IEnumerable <SqlTraceWireModel> >(sqlTraces => sentSqlTraces = sqlTraces);

            var sqlTracesToSend = new SqlTraceStatsCollection(maxTraces: 5);

            sqlTracesToSend.Insert(GetSqlTrace(6, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(5, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(4, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(3, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(2, maxCallTime: TimeSpan.FromSeconds(50)));
            sqlTracesToSend.Insert(GetSqlTrace(1, maxCallTime: TimeSpan.FromSeconds(50)));

            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();

            // Assert
            NrAssert.Multiple(
                () => Assert.AreEqual(sqlTracesPerPeriod, sentSqlTraces.Count()),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 5)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 4)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 3)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 2)),
                () => Assert.IsTrue(sentSqlTraces.Any(trace => trace.SqlId == 1))
                );
        }
        public void traces_are_aggregated_if_same_sql_id()
        {
            // Arrange
            var sentSqlTraces = null as IEnumerable <SqlTraceWireModel>;

            Mock.Arrange(() => _dataTransportService.Send(Arg.IsAny <IEnumerable <SqlTraceWireModel> >()))
            .DoInstead <IEnumerable <SqlTraceWireModel> >(sqlTraces => sentSqlTraces = sqlTraces);

            var sqlTracesToSend = new SqlTraceStatsCollection();

            sqlTracesToSend.Insert(GetSqlTrace(
                                       1,
                                       transactionName: "transactionName1",
                                       sql: "sql1",
                                       uri: "uri1",
                                       datastoreMetricName: "datastoreMetricName1",
                                       callCount: 1,
                                       minCallTime: TimeSpan.FromSeconds(5),
                                       maxCallTime: TimeSpan.FromSeconds(5),
                                       totalCallTime: TimeSpan.FromSeconds(5),
                                       parameterData: new Dictionary <string, object> {
                { "foo", "bar" }
            }
                                       ));
            sqlTracesToSend.Insert(GetSqlTrace(
                                       1,
                                       transactionName: "transactionName2",
                                       sql: "sql2",
                                       uri: "uri2",
                                       datastoreMetricName: "datastoreMetricName2",
                                       callCount: 1,
                                       minCallTime: TimeSpan.FromSeconds(3),
                                       maxCallTime: TimeSpan.FromSeconds(3),
                                       totalCallTime: TimeSpan.FromSeconds(3),
                                       parameterData: new Dictionary <string, object> {
                { "zip", "zap" }
            }
                                       ));

            _sqlTraceAggregator.Collect(sqlTracesToSend);

            // Act
            _harvestAction();

            // Assert
            Assert.AreEqual(1, sentSqlTraces.Count());
            var trace = sentSqlTraces.First();

            NrAssert.Multiple(
                () => Assert.AreEqual(1, sentSqlTraces.Count()),
                () => Assert.AreEqual(1, trace.SqlId),
                () => Assert.AreEqual("transactionName1", trace.TransactionName),
                () => Assert.AreEqual("sql1", trace.Sql),
                () => Assert.AreEqual("uri1", trace.Uri),
                () => Assert.AreEqual("datastoreMetricName1", trace.DatastoreMetricName),
                () => Assert.AreEqual(2, trace.CallCount),
                () => Assert.AreEqual(TimeSpan.FromSeconds(3), trace.MinCallTime),
                () => Assert.AreEqual(TimeSpan.FromSeconds(5), trace.MaxCallTime),
                () => Assert.AreEqual(TimeSpan.FromSeconds(8), trace.TotalCallTime),

                () => Assert.AreEqual(1, trace.ParameterData.Count),
                () => Assert.AreEqual("bar", trace.ParameterData["foo"])
                );
        }