1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
content / public / test / preloading_test_util.h [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_
#define CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_
#include <vector>
#include "base/memory/raw_ptr.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/browser/preloading.h"
#include "content/public/browser/preloading_data.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "third_party/blink/public/mojom/speculation_rules/speculation_rules.mojom-shared.h"
namespace content {
class PreloadingConfig;
namespace test {
// The set of UKM metric names in the PreloadingAttempt and PreloadingPrediction
// UKM logs. This is useful for calling TestUkmRecorder::GetEntries.
extern const std::vector<std::string> kPreloadingAttemptUkmMetrics;
extern const std::vector<std::string> kPreloadingPredictionUkmMetrics;
// Utility class to make building expected
// TestUkmRecorder::HumanReadableUkmEntry for EXPECT_EQ for PreloadingAttempt.
class PreloadingAttemptUkmEntryBuilder {
public:
explicit PreloadingAttemptUkmEntryBuilder(PreloadingPredictor predictor);
// This method assumes a navigation has occurred thus `TimeToNextNavigation`
// is set. Install `base::ScopedMockElapsedTimersForTest` into the test
// fixture to assert the entry's latency values' correctness.
//
// Optional `ready_time` should be set by the caller, if this attempt ever
// reaches `PreloadingTriggeringOutcome::kReady` state, at the time of
// reporting.
ukm::TestUkmRecorder::HumanReadableUkmEntry BuildEntry(
ukm::SourceId source_id,
PreloadingType preloading_type,
PreloadingEligibility eligibility,
PreloadingHoldbackStatus holdback_status,
PreloadingTriggeringOutcome triggering_outcome,
PreloadingFailureReason failure_reason,
bool accurate,
std::optional<base::TimeDelta> ready_time = std::nullopt,
std::optional<blink::mojom::SpeculationEagerness> eagerness =
std::nullopt) const;
private:
PreloadingPredictor predictor_;
};
// Utility class to make building expected
// TestUkmRecorder::HumanReadableUkmEntry for EXPECT_EQ for
// PreloadingPrediction.
class PreloadingPredictionUkmEntryBuilder {
public:
explicit PreloadingPredictionUkmEntryBuilder(PreloadingPredictor predictor);
// This method assumes a navigation has occurred thus `TimeToNextNavigation`
// is set. Install `base::ScopedMockElapsedTimersForTest` into the test
// fixture to assert the entry's latency values' correctness.
ukm::TestUkmRecorder::HumanReadableUkmEntry BuildEntry(
ukm::SourceId source_id,
int64_t confidence,
bool accurate_prediction) const;
private:
PreloadingPredictor predictor_;
};
// Checks if `ukm_recorder` recorded `expected_attempt_entries`. Doesn't care
// about the recording order.
void ExpectPreloadingAttemptUkm(
ukm::TestAutoSetUkmRecorder& ukm_recorder,
const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>&
expected_attempt_entries);
// Checks if `ukm_recorder` recorded `expected_prediction_entries`. Doesn't care
// about the recording order.
void ExpectPreloadingPredictionUkm(
ukm::TestAutoSetUkmRecorder& ukm_recorder,
const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>&
expected_prediction_entries);
// Turns a UKM entry into a human-readable string.
std::string UkmEntryToString(
const ukm::TestUkmRecorder::HumanReadableUkmEntry& entry);
// Turns two UKM entries into a human-readable string.
std::string ActualVsExpectedUkmEntryToString(
const ukm::TestUkmRecorder::HumanReadableUkmEntry& actual,
const ukm::TestUkmRecorder::HumanReadableUkmEntry& expected);
// Turns two collections of UKM entries into human-readable strings.
std::string ActualVsExpectedUkmEntriesToString(
const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>& actual,
const std::vector<ukm::TestUkmRecorder::HumanReadableUkmEntry>& expected);
// Utility class to access internal state from a PreloadingAttempt.
class PreloadingAttemptAccessor {
public:
explicit PreloadingAttemptAccessor(PreloadingAttempt* preloading_attempt);
PreloadingTriggeringOutcome GetTriggeringOutcome();
PreloadingFailureReason GetFailureReason();
private:
raw_ptr<PreloadingAttempt> preloading_attempt_;
};
// Creating a PreloadingConfigOverride will override the current
// PreloadingConfig (which is normally configured via field trial) until
// PreloadingConfigOverride is destroyed. By default the configuration disables
// sampling UKM preloading logs (some log types are sampled by default, which
// can make preloading tests that verify UKM logs flaky) but enables (i.e. does
// not hold back) all preloading features. For testing holdbacks, SetHoldback
// can be called to disable a particular preloading feature.
class PreloadingConfigOverride {
public:
PreloadingConfigOverride();
~PreloadingConfigOverride();
void SetHoldback(PreloadingType preloading_type,
PreloadingPredictor predictor,
bool holdback);
void SetHoldback(std::string_view preloading_type,
std::string_view predictor,
bool holdback);
private:
std::unique_ptr<PreloadingConfig> preloading_config_;
raw_ptr<PreloadingConfig> overridden_config_;
};
void SetHasSpeculationRulesPrerender(PreloadingData* preloading_data);
} // namespace test
} // namespace content
#endif // CONTENT_PUBLIC_TEST_PRELOADING_TEST_UTIL_H_