Home | History | Annotate | Download | only in performance_monitor
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 
      7 #include "base/strings/string_number_conversions.h"
      8 #include "base/time/time.h"
      9 #include "chrome/browser/performance_monitor/metric.h"
     10 #include "chrome/browser/ui/webui/performance_monitor/performance_monitor_ui_util.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace performance_monitor {
     14 
     15 class PerformanceMonitorUtilTest : public ::testing::Test {
     16  protected:
     17   // Helper method in order to access the otherwise-private AggregateInterval
     18   // method within the aggregation classes, so that we can test specific
     19   // aggregation methods without the extra burden of interval separation (which
     20   // is tested separately).
     21   scoped_ptr<Database::MetricVector> AggregateSingleInterval(
     22       MetricType type,
     23       const Database::MetricVector* metrics,
     24       const base::Time& start,
     25       const base::TimeDelta& resolution,
     26       AggregationMethod method) {
     27     const base::Time kMaxTime = base::Time::FromDoubleT(100);
     28     Database::MetricVector::const_iterator metric = metrics->begin();
     29     while (metric != metrics->end() && metric->time < start)
     30       ++metric;
     31 
     32     scoped_ptr<Aggregator> aggregator;
     33     switch (method) {
     34       case AGGREGATION_METHOD_NONE:
     35         aggregator.reset(new NoAggregation());
     36         break;
     37       case AGGREGATION_METHOD_MEDIAN:
     38         aggregator.reset(new MedianAggregation());
     39         break;
     40       case AGGREGATION_METHOD_MEAN:
     41         aggregator.reset(new MeanAggregation());
     42         break;
     43       default:
     44         NOTREACHED();
     45         return scoped_ptr<Database::MetricVector>();
     46     }
     47     return aggregator->AggregateInterval(
     48         type, &metric, metrics->end(), start, kMaxTime, resolution);
     49   }
     50 };
     51 
     52 TEST_F(PerformanceMonitorUtilTest, AggregateMetricEmptyTest) {
     53   Database::MetricVector metric_vector;
     54   const base::Time data_time = base::Time::FromDoubleT(1);
     55   metric_vector.push_back(Metric(METRIC_CPU_USAGE, data_time, 1));
     56 
     57   const base::Time results_time = base::Time::FromDoubleT(3);
     58   const base::TimeDelta resolution = base::TimeDelta::FromSeconds(1);
     59   scoped_ptr<Database::MetricVector> aggregated_metric =
     60       AggregateSingleInterval(METRIC_CPU_USAGE,
     61                               &metric_vector,
     62                               results_time,
     63                               resolution,
     64                               AGGREGATION_METHOD_MEAN);
     65   ASSERT_EQ(0u, aggregated_metric->size());
     66   aggregated_metric = AggregateSingleInterval(METRIC_CPU_USAGE,
     67                                               &metric_vector,
     68                                               results_time,
     69                                               resolution,
     70                                               AGGREGATION_METHOD_MEDIAN);
     71   ASSERT_EQ(0u, aggregated_metric->size());
     72 }
     73 
     74 TEST_F(PerformanceMonitorUtilTest, AggregateMetricSimpleTest) {
     75   const base::Time data_time = base::Time::FromDoubleT(2);
     76   const base::Time results_time = base::Time::FromDoubleT(1);
     77   const base::TimeDelta results_resolution = base::TimeDelta::FromSeconds(2);
     78 
     79   const double value = 3.14;
     80   Database::MetricVector metric_vector;
     81   metric_vector.push_back(Metric(METRIC_CPU_USAGE, data_time, value));
     82   Database::MetricVector aggregated_metric =
     83       *AggregateSingleInterval(METRIC_CPU_USAGE,
     84                                &metric_vector,
     85                                results_time,
     86                                results_resolution,
     87                                AGGREGATION_METHOD_MEAN);
     88 
     89   ASSERT_EQ(1u, aggregated_metric.size());
     90   EXPECT_EQ(results_time + results_resolution, aggregated_metric[0].time);
     91   EXPECT_EQ(value, aggregated_metric[0].value);
     92 
     93   aggregated_metric = *AggregateSingleInterval(METRIC_CPU_USAGE,
     94                                                &metric_vector,
     95                                                results_time,
     96                                                results_resolution,
     97                                                AGGREGATION_METHOD_MEDIAN);
     98   ASSERT_EQ(1u, aggregated_metric.size());
     99   EXPECT_EQ(results_time + results_resolution, aggregated_metric[0].time);
    100   EXPECT_EQ(value, aggregated_metric[0].value);
    101 }
    102 
    103 TEST_F(PerformanceMonitorUtilTest, AggregateMetricDenseTest) {
    104   base::Time current_data_time = base::Time::FromDoubleT(2);
    105   const base::TimeDelta data_resolution = base::TimeDelta::FromSeconds(1);
    106   const base::Time results_time = base::Time::FromDoubleT(6);
    107   const base::TimeDelta results_resolution = base::TimeDelta::FromSeconds(4);
    108   double current_value = 1;
    109   int num_points = 12;
    110   Database::MetricVector metric_vector;
    111 
    112   for (int i = 0; i < num_points; ++i) {
    113     metric_vector.push_back(Metric(METRIC_CPU_USAGE,
    114                                    current_data_time,
    115                                    current_value));
    116     current_value *= 2;
    117     current_data_time += data_resolution;
    118   }
    119   Database::MetricVector aggregated_metric =
    120       *AggregateSingleInterval(METRIC_CPU_USAGE,
    121                                &metric_vector,
    122                                results_time,
    123                                results_resolution,
    124                                AGGREGATION_METHOD_MEAN);
    125   // The first 4 points get ignored because they are before the start time.
    126   // The remaining 8 points are aggregated into two data points.
    127   ASSERT_EQ(2u, aggregated_metric.size());
    128   EXPECT_EQ(results_time + results_resolution, aggregated_metric[0].time);
    129   EXPECT_DOUBLE_EQ((32 + 64 + 128 + 256) / 4.0, aggregated_metric[0].value);
    130   EXPECT_EQ(results_time + (2 * results_resolution),
    131             aggregated_metric[1].time);
    132   // Since we don't have data for the time of 14, we stretch out the 2048.
    133   EXPECT_DOUBLE_EQ((512 + 1024 + 2048 + 2048) / 4.0,
    134                    aggregated_metric[1].value);
    135 
    136   aggregated_metric = *AggregateSingleInterval(METRIC_CPU_USAGE,
    137                                                &metric_vector,
    138                                                results_time,
    139                                                results_resolution,
    140                                                AGGREGATION_METHOD_MEDIAN);
    141   ASSERT_EQ(2u, aggregated_metric.size());
    142   EXPECT_EQ(results_time + results_resolution, aggregated_metric[0].time);
    143   EXPECT_EQ(results_time + 2 * results_resolution,
    144             aggregated_metric[1].time);
    145   EXPECT_EQ(48, aggregated_metric[0].value);
    146   EXPECT_EQ(768, aggregated_metric[1].value);
    147 }
    148 
    149 TEST_F(PerformanceMonitorUtilTest, AggregateMetricSparseTest) {
    150   Database::MetricVector metric_vector;
    151 
    152   const base::Time data_time1 = base::Time::FromDoubleT(20);
    153   const double value1 = 3.14;
    154   metric_vector.push_back(Metric(METRIC_CPU_USAGE, data_time1, value1));
    155   const base::Time data_time2 = base::Time::FromDoubleT(40);
    156   const double value2 = 6.28;
    157   metric_vector.push_back(Metric(METRIC_CPU_USAGE, data_time2, value2));
    158   const base::Time data_time3 = base::Time::FromDoubleT(60);
    159   const double value3 = 9.42;
    160   metric_vector.push_back(Metric(METRIC_CPU_USAGE, data_time3, value3));
    161 
    162   const base::Time results_time = base::Time::FromDoubleT(19);
    163   const base::TimeDelta results_resolution = base::TimeDelta::FromSeconds(2);
    164   Database::MetricVector aggregated_metric =
    165       *AggregateSingleInterval(METRIC_CPU_USAGE,
    166                                &metric_vector,
    167                                results_time,
    168                                results_resolution,
    169                                AGGREGATION_METHOD_MEAN);
    170 
    171   // The first aggregation point is split between the first value and the second
    172   // value. The second is split between the second and third. The third doesn't
    173   // have any data after it so the aggregation is the same value.
    174   ASSERT_EQ(3u, aggregated_metric.size());
    175   EXPECT_EQ(results_time + 1 * results_resolution,
    176             aggregated_metric[0].time);
    177   EXPECT_EQ((value1 + value2) / 2, aggregated_metric[0].value);
    178   EXPECT_EQ(results_time + 11 * results_resolution,
    179             aggregated_metric[1].time);
    180   EXPECT_EQ((value2 + value3) / 2, aggregated_metric[1].value);
    181   EXPECT_EQ(results_time + 21 * results_resolution,
    182             aggregated_metric[2].time);
    183   EXPECT_EQ(value3, aggregated_metric[2].value);
    184 
    185   // For median values, we go from [start, end). Thus, since each of these are
    186   // one window apart, each value will have it's own window.
    187   aggregated_metric = *AggregateSingleInterval(METRIC_CPU_USAGE,
    188                                                &metric_vector,
    189                                                results_time,
    190                                                results_resolution,
    191                                                AGGREGATION_METHOD_MEDIAN);
    192   ASSERT_EQ(3u, aggregated_metric.size());
    193   EXPECT_EQ(results_time + 1 * results_resolution,
    194             aggregated_metric[0].time);
    195   EXPECT_EQ(value1, aggregated_metric[0].value);
    196   EXPECT_EQ(results_time + 11 * results_resolution,
    197             aggregated_metric[1].time);
    198   EXPECT_EQ(value2, aggregated_metric[1].value);
    199   EXPECT_EQ(results_time + 21 * results_resolution,
    200             aggregated_metric[2].time);
    201   EXPECT_EQ(value3, aggregated_metric[2].value);
    202 }
    203 
    204 TEST_F(PerformanceMonitorUtilTest, AggregateMetricMultipleIntervals) {
    205   base::Time current_data_time = base::Time::FromDoubleT(1);
    206   Database::MetricVector metric_vector;
    207 
    208   const int kNumMetrics = 20;
    209   for (int i = 0; i < kNumMetrics; ++i) {
    210     metric_vector.push_back(Metric(METRIC_CPU_USAGE,
    211                                    current_data_time,
    212                                    i + 1));
    213     current_data_time += base::TimeDelta::FromSeconds(1);
    214   }
    215 
    216   std::vector<TimeRange> time_ranges;
    217   time_ranges.push_back(TimeRange(base::Time::FromDoubleT(2),
    218                                   base::Time::FromDoubleT(10)));
    219   time_ranges.push_back(TimeRange(base::Time::FromDoubleT(12),
    220                                   base::Time::FromDoubleT(22)));
    221 
    222   std::vector<Database::MetricVector> results =
    223       *AggregateMetric(METRIC_CPU_USAGE,
    224                        &metric_vector,
    225                        base::Time::FromDoubleT(2),
    226                        time_ranges,
    227                        base::TimeDelta::FromSeconds(1),
    228                        AGGREGATION_METHOD_NONE);
    229 
    230   ASSERT_EQ(2u, results.size());
    231   Database::MetricVector metric_series = results[0];
    232   ASSERT_EQ(9u, metric_series.size());
    233   double expected = 2;
    234   for (Database::MetricVector::const_iterator iter = metric_series.begin();
    235        iter != metric_series.end(); ++iter) {
    236     EXPECT_EQ(expected, iter->value);
    237     EXPECT_EQ(base::Time::FromDoubleT(expected), iter->time);
    238     ++expected;
    239   }
    240 
    241   metric_series = results[1];
    242   ASSERT_EQ(9u, metric_series.size());
    243   expected = 12;
    244   for (Database::MetricVector::const_iterator iter = metric_series.begin();
    245        iter != metric_series.end(); ++iter) {
    246     EXPECT_EQ(expected, iter->value);
    247     EXPECT_EQ(base::Time::FromDoubleT(expected), iter->time);
    248     ++expected;
    249   }
    250 }
    251 
    252 }  // namespace performance_monitor
    253