OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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 "ios/chrome/test/app/histogram_test_util.h" |
| 6 |
| 7 #import <Foundation/Foundation.h> |
| 8 |
| 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/metrics/histogram.h" |
| 11 #include "base/metrics/histogram_samples.h" |
| 12 #include "base/metrics/metrics_hashes.h" |
| 13 #include "base/metrics/sample_map.h" |
| 14 #include "base/metrics/statistics_recorder.h" |
| 15 #include "base/stl_util.h" |
| 16 |
| 17 namespace { |
| 18 base::HistogramBase* FindHistogram(const std::string& name, |
| 19 FailureBlock failure_block) { |
| 20 base::HistogramBase* histogram = |
| 21 base::StatisticsRecorder::FindHistogram(name); |
| 22 if (!histogram && failure_block) { |
| 23 failure_block([NSString |
| 24 stringWithFormat:@"Histogram %s does not exist", name.c_str()]); |
| 25 } |
| 26 return histogram; |
| 27 } |
| 28 } // namespace |
| 29 |
| 30 namespace chrome_test_util { |
| 31 |
| 32 HistogramTester::HistogramTester() { |
| 33 base::StatisticsRecorder::Initialize(); // Safe to call multiple times. |
| 34 |
| 35 // Record any histogram data that exists when the object is created so it can |
| 36 // be subtracted later. |
| 37 base::StatisticsRecorder::Histograms histograms; |
| 38 base::StatisticsRecorder::GetSnapshot(std::string(), &histograms); |
| 39 for (size_t i = 0; i < histograms.size(); ++i) { |
| 40 std::unique_ptr<base::HistogramSamples> samples( |
| 41 histograms[i]->SnapshotSamples()); |
| 42 histograms_snapshot_[histograms[i]->histogram_name()] = std::move(samples); |
| 43 } |
| 44 } |
| 45 |
| 46 HistogramTester::~HistogramTester() { |
| 47 histograms_snapshot_.clear(); |
| 48 } |
| 49 |
| 50 BOOL HistogramTester::ExpectUniqueSample( |
| 51 const std::string& name, |
| 52 base::HistogramBase::Sample sample, |
| 53 base::HistogramBase::Count expected_count, |
| 54 FailureBlock failure_block) const { |
| 55 base::HistogramBase* histogram = FindHistogram(name, failure_block); |
| 56 if (!histogram) { |
| 57 return NO; |
| 58 } |
| 59 |
| 60 std::unique_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); |
| 61 if (!CheckBucketCount(name, sample, expected_count, *samples, |
| 62 failure_block)) { |
| 63 return NO; |
| 64 } |
| 65 if (!CheckTotalCount(name, expected_count, *samples, failure_block)) { |
| 66 return NO; |
| 67 } |
| 68 return YES; |
| 69 } |
| 70 |
| 71 BOOL HistogramTester::ExpectBucketCount( |
| 72 const std::string& name, |
| 73 base::HistogramBase::Sample sample, |
| 74 base::HistogramBase::Count expected_count, |
| 75 FailureBlock failure_block) const { |
| 76 BOOL not_found_fails = expected_count > 0; |
| 77 FailureBlock not_found_block = |
| 78 not_found_fails ? failure_block : static_cast<FailureBlock>(nil); |
| 79 base::HistogramBase* histogram = FindHistogram(name, not_found_block); |
| 80 if (!histogram) { |
| 81 return !not_found_fails; |
| 82 } |
| 83 |
| 84 std::unique_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); |
| 85 return CheckBucketCount(name, sample, expected_count, *samples, |
| 86 failure_block); |
| 87 } |
| 88 |
| 89 BOOL HistogramTester::ExpectTotalCount(const std::string& name, |
| 90 base::HistogramBase::Count count, |
| 91 FailureBlock failure_block) const { |
| 92 BOOL not_found_fails = count > 0; |
| 93 FailureBlock not_found_block = |
| 94 not_found_fails ? failure_block : static_cast<FailureBlock>(nil); |
| 95 base::HistogramBase* histogram = FindHistogram(name, not_found_block); |
| 96 if (!histogram) { |
| 97 return !not_found_fails; |
| 98 } |
| 99 std::unique_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples()); |
| 100 return CheckTotalCount(name, count, *samples, failure_block); |
| 101 } |
| 102 |
| 103 std::vector<Bucket> HistogramTester::GetAllSamples( |
| 104 const std::string& name) const { |
| 105 std::vector<Bucket> samples; |
| 106 std::unique_ptr<base::HistogramSamples> snapshot = |
| 107 GetHistogramSamplesSinceCreation(name); |
| 108 if (snapshot) { |
| 109 for (auto it = snapshot->Iterator(); !it->Done(); it->Next()) { |
| 110 base::HistogramBase::Sample sample; |
| 111 base::HistogramBase::Count count; |
| 112 it->Get(&sample, nullptr, &count); |
| 113 samples.push_back(Bucket(sample, count)); |
| 114 } |
| 115 } |
| 116 return samples; |
| 117 } |
| 118 |
| 119 std::unique_ptr<base::HistogramSamples> |
| 120 HistogramTester::GetHistogramSamplesSinceCreation( |
| 121 const std::string& histogram_name) const { |
| 122 base::HistogramBase* histogram = |
| 123 base::StatisticsRecorder::FindHistogram(histogram_name); |
| 124 // Whether the histogram exists or not may not depend on the current test |
| 125 // calling this method, but rather on which tests ran before and possibly |
| 126 // generated a histogram or not (see http://crbug.com/473689). To provide a |
| 127 // response which is independent of the previously run tests, this method |
| 128 // creates empty samples in the absence of the histogram, rather than |
| 129 // returning null. |
| 130 if (!histogram) { |
| 131 return std::unique_ptr<base::HistogramSamples>( |
| 132 new base::SampleMap(base::HashMetricName(histogram_name))); |
| 133 } |
| 134 std::unique_ptr<base::HistogramSamples> named_samples( |
| 135 histogram->SnapshotSamples()); |
| 136 auto original_samples_it = histograms_snapshot_.find(histogram_name); |
| 137 if (original_samples_it != histograms_snapshot_.end()) |
| 138 named_samples->Subtract(*original_samples_it->second); |
| 139 return named_samples; |
| 140 } |
| 141 |
| 142 BOOL HistogramTester::CheckBucketCount( |
| 143 const std::string& name, |
| 144 base::HistogramBase::Sample sample, |
| 145 base::HistogramBase::Count expected_count, |
| 146 const base::HistogramSamples& samples, |
| 147 FailureBlock failure_block) const { |
| 148 int actual_count = samples.GetCount(sample); |
| 149 auto histogram_data = histograms_snapshot_.find(name); |
| 150 if (histogram_data != histograms_snapshot_.end()) |
| 151 actual_count -= histogram_data->second->GetCount(sample); |
| 152 if (expected_count == actual_count) { |
| 153 return YES; |
| 154 } |
| 155 if (failure_block) { |
| 156 failure_block([NSString |
| 157 stringWithFormat: |
| 158 @"Histogram \"%s\" doe not have the " |
| 159 "right number of samples(%d) in the expected bucket(%d). It has " |
| 160 "(%d).", |
| 161 name.c_str(), expected_count, sample, actual_count]); |
| 162 } |
| 163 return NO; |
| 164 } |
| 165 |
| 166 BOOL HistogramTester::CheckTotalCount(const std::string& name, |
| 167 base::HistogramBase::Count expected_count, |
| 168 const base::HistogramSamples& samples, |
| 169 FailureBlock failure_block) const { |
| 170 int actual_count = samples.TotalCount(); |
| 171 auto histogram_data = histograms_snapshot_.find(name); |
| 172 if (histogram_data != histograms_snapshot_.end()) |
| 173 actual_count -= histogram_data->second->TotalCount(); |
| 174 if (expected_count == actual_count) { |
| 175 return YES; |
| 176 } |
| 177 if (failure_block) { |
| 178 failure_block( |
| 179 [NSString stringWithFormat:@"Histogram \"%s\" doe not have the " |
| 180 "right total number of samples(%d). It has " |
| 181 "(%d).", |
| 182 name.c_str(), expected_count, actual_count]); |
| 183 } |
| 184 return NO; |
| 185 } |
| 186 |
| 187 } // namespace chrome_test_util |
OLD | NEW |