1 // Copyright 2017 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.
5 #include "components/ukm/test_ukm_recorder.h"
10 #include "base/logging.h"
11 #include "base/metrics/metrics_hashes.h"
12 #include "base/task_scheduler/post_task.h"
13 #include "base/threading/sequenced_task_runner_handle.h"
14 #include "components/ukm/ukm_source.h"
15 #include "services/metrics/public/cpp/delegating_ukm_recorder.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 // Merge the data from |in| to |out|.
23 void MergeEntry(const mojom::UkmEntry* in, mojom::UkmEntry* out) {
24 if (out->event_hash) {
25 EXPECT_EQ(out->source_id, in->source_id);
26 EXPECT_EQ(out->event_hash, in->event_hash);
28 out->event_hash = in->event_hash;
29 out->source_id = in->source_id;
31 for (const auto& metric : in->metrics) {
32 out->metrics.emplace(metric);
38 TestUkmRecorder::TestUkmRecorder() {
39 EnableRecording(/*extensions=*/true);
40 StoreWhitelistedEntries();
41 DisableSamplingForTesting();
44 TestUkmRecorder::~TestUkmRecorder() {
47 bool TestUkmRecorder::ShouldRestrictToWhitelistedSourceIds() const {
48 // In tests, we want to record all source ids (not just those that are
53 bool TestUkmRecorder::ShouldRestrictToWhitelistedEntries() const {
54 // In tests, we want to record all entries (not just those that are
59 const UkmSource* TestUkmRecorder::GetSourceForSourceId(
60 SourceId source_id) const {
61 const UkmSource* source = nullptr;
62 for (const auto& kv : sources()) {
63 if (kv.second->id() == source_id) {
64 DCHECK_EQ(nullptr, source);
65 source = kv.second.get();
71 std::vector<const mojom::UkmEntry*> TestUkmRecorder::GetEntriesByName(
72 base::StringPiece entry_name) const {
73 uint64_t hash = base::HashMetricName(entry_name);
74 std::vector<const mojom::UkmEntry*> result;
75 for (const auto& it : entries()) {
76 if (it->event_hash == hash)
77 result.push_back(it.get());
82 std::map<ukm::SourceId, mojom::UkmEntryPtr>
83 TestUkmRecorder::GetMergedEntriesByName(base::StringPiece entry_name) const {
84 uint64_t hash = base::HashMetricName(entry_name);
85 std::map<ukm::SourceId, mojom::UkmEntryPtr> result;
86 for (const auto& it : entries()) {
87 if (it->event_hash != hash)
89 mojom::UkmEntryPtr& entry_ptr = result[it->source_id];
91 entry_ptr = mojom::UkmEntry::New();
92 MergeEntry(it.get(), entry_ptr.get());
97 void TestUkmRecorder::ExpectEntrySourceHasUrl(const mojom::UkmEntry* entry,
98 const GURL& url) const {
99 const UkmSource* src = GetSourceForSourceId(entry->source_id);
100 if (src == nullptr) {
101 FAIL() << "Entry source id has no associated Source.";
104 EXPECT_EQ(src->url(), url);
108 bool TestUkmRecorder::EntryHasMetric(const mojom::UkmEntry* entry,
109 base::StringPiece metric_name) {
110 return GetEntryMetric(entry, metric_name) != nullptr;
114 const int64_t* TestUkmRecorder::GetEntryMetric(const mojom::UkmEntry* entry,
115 base::StringPiece metric_name) {
116 uint64_t hash = base::HashMetricName(metric_name);
117 const auto it = entry->metrics.find(hash);
118 if (it != entry->metrics.end())
124 void TestUkmRecorder::ExpectEntryMetric(const mojom::UkmEntry* entry,
125 base::StringPiece metric_name,
126 int64_t expected_value) {
127 const int64_t* metric = GetEntryMetric(entry, metric_name);
128 if (metric == nullptr) {
129 FAIL() << "Failed to find metric for event: " << metric_name;
132 EXPECT_EQ(expected_value, *metric) << " for metric:" << metric_name;
135 TestAutoSetUkmRecorder::TestAutoSetUkmRecorder() : self_ptr_factory_(this) {
136 DelegatingUkmRecorder::Get()->AddDelegate(self_ptr_factory_.GetWeakPtr());
139 TestAutoSetUkmRecorder::~TestAutoSetUkmRecorder() {
140 DelegatingUkmRecorder::Get()->RemoveDelegate(this);