// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/test/base/uma_histogram_helper.h"
#include "base/bind.h"
#include "base/metrics/statistics_recorder.h"
#include "base/test/test_timeouts.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/histogram_fetcher.h"
UMAHistogramHelper::UMAHistogramHelper() {
base::StatisticsRecorder::Initialize();
}
UMAHistogramHelper::~UMAHistogramHelper() {
}
void UMAHistogramHelper::PrepareSnapshot(const char* const histogram_names[],
size_t num_histograms) {
for (size_t i = 0; i < num_histograms; ++i) {
std::string histogram_name = histogram_names[i];
base::HistogramBase* histogram =
base::StatisticsRecorder::FindHistogram(histogram_name);
// If there is no histogram present, then don't record a snapshot. The logic
// in the Expect* methods will act to treat no histogram equivalent to
// samples with zeros.
if (histogram) {
histogram_snapshots[histogram_name] =
make_linked_ptr(histogram->SnapshotSamples().release());
}
}
}
void UMAHistogramHelper::Fetch() {
base::Closure callback = base::Bind(&UMAHistogramHelper::FetchCallback,
base::Unretained(this));
content::FetchHistogramsAsynchronously(
base::MessageLoop::current(),
callback,
// If this call times out, it means that a child process is not
// responding, which is something we should not ignore. The timeout is
// set to be longer than the normal browser test timeout so that it will
// be prempted by the normal timeout.
TestTimeouts::action_max_timeout() * 2);
content::RunMessageLoop();
}
void UMAHistogramHelper::ExpectUniqueSample(
const std::string& name,
base::HistogramBase::Sample sample,
base::HistogramBase::Count expected_count) {
base::HistogramBase* histogram =
base::StatisticsRecorder::FindHistogram(name);
EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram)
<< "Histogram \"" << name << "\" does not exist.";
if (histogram) {
scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
CheckBucketCount(name, sample, expected_count, *samples);
CheckTotalCount(name, expected_count, *samples);
}
}
void UMAHistogramHelper::ExpectBucketCount(
const std::string& name,
base::HistogramBase::Sample sample,
base::HistogramBase::Count expected_count) {
base::HistogramBase* histogram =
base::StatisticsRecorder::FindHistogram(name);
EXPECT_NE(static_cast<base::HistogramBase*>(NULL), histogram)
<< "Histogram \"" << name << "\" does not exist.";
if (histogram) {
scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
CheckBucketCount(name, sample, expected_count, *samples);
}
}
void UMAHistogramHelper::ExpectTotalCount(
const std::string& name,
base::HistogramBase::Count count) {
base::HistogramBase* histogram =
base::StatisticsRecorder::FindHistogram(name);
if (histogram) {
scoped_ptr<base::HistogramSamples> samples(histogram->SnapshotSamples());
CheckTotalCount(name, count, *samples);
} else {
// No histogram means there were zero samples.
EXPECT_EQ(count, 0) << "Histogram \"" << name << "\" does not exist.";
}
}
void UMAHistogramHelper::FetchCallback() {
base::MessageLoopForUI::current()->Quit();
}
void UMAHistogramHelper::CheckBucketCount(
const std::string& name,
base::HistogramBase::Sample sample,
base::HistogramBase::Count expected_count,
base::HistogramSamples& samples) {
int actual_count = samples.GetCount(sample);
if (histogram_snapshots.count(name))
actual_count -= histogram_snapshots[name]->GetCount(sample);
EXPECT_EQ(expected_count, actual_count)
<< "Histogram \"" << name
<< "\" does not have the right number of samples (" << expected_count
<< ") in the expected bucket (" << sample << "). It has (" << actual_count
<< ").";
}
void UMAHistogramHelper::CheckTotalCount(
const std::string& name,
base::HistogramBase::Count expected_count,
base::HistogramSamples& samples) {
int actual_count = samples.TotalCount();
if (histogram_snapshots.count(name))
actual_count -= histogram_snapshots[name]->TotalCount();
EXPECT_EQ(expected_count, actual_count)
<< "Histogram \"" << name
<< "\" does not have the right total number of samples ("
<< expected_count << "). It has (" << actual_count << ").";
}