123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- // Copyright 2017 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 "components/ukm/test_ukm_recorder.h"
- #include <algorithm>
- #include <iterator>
- #include "base/check_op.h"
- #include "base/metrics/metrics_hashes.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "services/metrics/public/cpp/delegating_ukm_recorder.h"
- #include "services/metrics/public/cpp/ukm_builders.h"
- #include "services/metrics/public/cpp/ukm_source.h"
- #include "testing/gtest/include/gtest/gtest.h"
- namespace ukm {
- namespace {
- // Merge the data from |in| to |out|.
- void MergeEntry(const mojom::UkmEntry* in, mojom::UkmEntry* out) {
- if (out->event_hash) {
- EXPECT_EQ(out->source_id, in->source_id);
- EXPECT_EQ(out->event_hash, in->event_hash);
- } else {
- out->event_hash = in->event_hash;
- out->source_id = in->source_id;
- }
- for (const auto& metric : in->metrics) {
- out->metrics.emplace(metric);
- }
- }
- } // namespace
- TestUkmRecorder::TestUkmRecorder() {
- EnableRecording(/*extensions=*/true);
- InitDecodeMap();
- SetSamplingForTesting(1); // 1-in-1 == unsampled
- }
- TestUkmRecorder::~TestUkmRecorder() {}
- bool TestUkmRecorder::ShouldRestrictToWhitelistedSourceIds() const {
- // In tests, we want to record all source ids (not just those that are
- // whitelisted).
- return false;
- }
- void TestUkmRecorder::AddEntry(mojom::UkmEntryPtr entry) {
- const bool should_run_callback =
- on_add_entry_ && entry && entry_hash_to_wait_for_ == entry->event_hash;
- UkmRecorderImpl::AddEntry(std::move(entry));
- if (should_run_callback)
- on_add_entry_.Run();
- }
- const UkmSource* TestUkmRecorder::GetSourceForSourceId(
- SourceId source_id) const {
- const UkmSource* source = nullptr;
- for (const auto& kv : sources()) {
- if (kv.second->id() == source_id) {
- DCHECK_EQ(nullptr, source);
- source = kv.second.get();
- }
- }
- return source;
- }
- const ukm::mojom::UkmEntry* TestUkmRecorder::GetDocumentCreatedEntryForSourceId(
- ukm::SourceId source_id) const {
- auto entries = GetEntriesByName(ukm::builders::DocumentCreated::kEntryName);
- for (auto* entry : entries) {
- if (entry->source_id == source_id)
- return entry;
- }
- return nullptr;
- }
- void TestUkmRecorder::SetOnAddEntryCallback(
- base::StringPiece entry_name,
- base::RepeatingClosure on_add_entry) {
- on_add_entry_ = std::move(on_add_entry);
- entry_hash_to_wait_for_ = base::HashMetricName(entry_name);
- }
- std::vector<const mojom::UkmEntry*> TestUkmRecorder::GetEntriesByName(
- base::StringPiece entry_name) const {
- uint64_t hash = base::HashMetricName(entry_name);
- std::vector<const mojom::UkmEntry*> result;
- for (const auto& it : entries()) {
- if (it->event_hash == hash)
- result.push_back(it.get());
- }
- return result;
- }
- std::map<ukm::SourceId, mojom::UkmEntryPtr>
- TestUkmRecorder::GetMergedEntriesByName(base::StringPiece entry_name) const {
- uint64_t hash = base::HashMetricName(entry_name);
- std::map<ukm::SourceId, mojom::UkmEntryPtr> result;
- for (const auto& it : entries()) {
- if (it->event_hash != hash)
- continue;
- mojom::UkmEntryPtr& entry_ptr = result[it->source_id];
- if (!entry_ptr)
- entry_ptr = mojom::UkmEntry::New();
- MergeEntry(it.get(), entry_ptr.get());
- }
- return result;
- }
- void TestUkmRecorder::ExpectEntrySourceHasUrl(const mojom::UkmEntry* entry,
- const GURL& url) const {
- const UkmSource* src = GetSourceForSourceId(entry->source_id);
- if (src == nullptr) {
- FAIL() << "Entry source id has no associated Source.";
- }
- EXPECT_EQ(src->url(), url);
- }
- // static
- bool TestUkmRecorder::EntryHasMetric(const mojom::UkmEntry* entry,
- base::StringPiece metric_name) {
- return GetEntryMetric(entry, metric_name) != nullptr;
- }
- // static
- const int64_t* TestUkmRecorder::GetEntryMetric(const mojom::UkmEntry* entry,
- base::StringPiece metric_name) {
- uint64_t hash = base::HashMetricName(metric_name);
- const auto it = entry->metrics.find(hash);
- if (it != entry->metrics.end())
- return &it->second;
- return nullptr;
- }
- // static
- void TestUkmRecorder::ExpectEntryMetric(const mojom::UkmEntry* entry,
- base::StringPiece metric_name,
- int64_t expected_value) {
- const int64_t* metric = GetEntryMetric(entry, metric_name);
- if (metric == nullptr) {
- FAIL() << "Failed to find metric for event: " << metric_name;
- }
- EXPECT_EQ(expected_value, *metric) << " for metric:" << metric_name;
- }
- TestAutoSetUkmRecorder::TestAutoSetUkmRecorder() {
- DelegatingUkmRecorder::Get()->AddDelegate(self_ptr_factory_.GetWeakPtr());
- }
- TestAutoSetUkmRecorder::~TestAutoSetUkmRecorder() {
- DelegatingUkmRecorder::Get()->RemoveDelegate(this);
- }
- std::vector<TestUkmRecorder::HumanReadableUkmMetrics>
- TestUkmRecorder::GetMetrics(
- std::string entry_name,
- const std::vector<std::string>& metric_names) const {
- std::vector<TestUkmRecorder::HumanReadableUkmMetrics> result;
- for (const auto& entry : GetEntries(entry_name, metric_names)) {
- result.push_back(entry.metrics);
- }
- return result;
- }
- std::vector<TestUkmRecorder::HumanReadableUkmEntry> TestUkmRecorder::GetEntries(
- std::string entry_name,
- const std::vector<std::string>& metric_names) const {
- std::vector<TestUkmRecorder::HumanReadableUkmEntry> results;
- for (const ukm::mojom::UkmEntry* entry : GetEntriesByName(entry_name)) {
- HumanReadableUkmEntry result;
- result.source_id = entry->source_id;
- for (const std::string& metric_name : metric_names) {
- const int64_t* metric_value =
- ukm::TestUkmRecorder::GetEntryMetric(entry, metric_name);
- if (metric_value)
- result.metrics[metric_name] = *metric_value;
- }
- results.push_back(std::move(result));
- }
- return results;
- }
- std::vector<ukm::TestAutoSetUkmRecorder::HumanReadableUkmMetrics>
- TestUkmRecorder::FilteredHumanReadableMetricForEntry(
- const std::string& entry_name,
- const std::string& metric_name) const {
- std::vector<std::string> metric_name_vector(1, metric_name);
- auto metrics = GetMetrics(entry_name, metric_name_vector);
- std::vector<ukm::TestAutoSetUkmRecorder::HumanReadableUkmMetrics>
- filtered_result;
- std::copy_if(
- metrics.begin(), metrics.end(), std::back_inserter(filtered_result),
- [&metric_name](
- ukm::TestAutoSetUkmRecorder::HumanReadableUkmMetrics metric) {
- if (metric.empty())
- return false;
- return metric.begin()->first == metric_name;
- });
- return filtered_result;
- }
- TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry() = default;
- TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry(
- ukm::SourceId source_id,
- TestUkmRecorder::HumanReadableUkmMetrics ukm_metrics)
- : source_id(source_id), metrics(std::move(ukm_metrics)) {}
- TestUkmRecorder::HumanReadableUkmEntry::HumanReadableUkmEntry(
- const HumanReadableUkmEntry&) = default;
- TestUkmRecorder::HumanReadableUkmEntry::~HumanReadableUkmEntry() = default;
- bool TestUkmRecorder::HumanReadableUkmEntry::operator==(
- const HumanReadableUkmEntry& other) const {
- return source_id == other.source_id && metrics == other.metrics;
- }
- } // namespace ukm
|