OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/reporting/reporting_endpoint_manager.h" | 5 #include "net/reporting/reporting_endpoint_manager.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/test/simple_test_tick_clock.h" | 9 #include "base/test/simple_test_tick_clock.h" |
10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
11 #include "net/base/backoff_entry.h" | 11 #include "net/base/backoff_entry.h" |
12 #include "net/reporting/reporting_cache.h" | 12 #include "net/reporting/reporting_cache.h" |
13 #include "net/reporting/reporting_client.h" | 13 #include "net/reporting/reporting_client.h" |
| 14 #include "net/reporting/reporting_policy.h" |
14 #include "net/reporting/reporting_test_util.h" | 15 #include "net/reporting/reporting_test_util.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 #include "url/gurl.h" | 17 #include "url/gurl.h" |
17 #include "url/origin.h" | 18 #include "url/origin.h" |
18 | 19 |
19 namespace net { | 20 namespace net { |
20 namespace { | 21 namespace { |
21 | 22 |
22 class ReportingEndpointManagerTest : public ::testing::Test { | 23 class ReportingEndpointManagerTest : public ReportingTestBase { |
23 protected: | 24 protected: |
24 ReportingEndpointManagerTest() | |
25 : manager_(&clock_, &cache_, &backoff_policy_) { | |
26 backoff_policy_.num_errors_to_ignore = 0; | |
27 backoff_policy_.initial_delay_ms = 60000; | |
28 backoff_policy_.multiply_factor = 2.0; | |
29 backoff_policy_.jitter_factor = 0.0; | |
30 backoff_policy_.maximum_backoff_ms = -1; | |
31 backoff_policy_.entry_lifetime_ms = 0; | |
32 backoff_policy_.always_use_initial_delay = false; | |
33 } | |
34 | |
35 base::TimeTicks yesterday() { | |
36 return clock_.NowTicks() - base::TimeDelta::FromDays(1); | |
37 } | |
38 | |
39 base::TimeTicks tomorrow() { | |
40 return clock_.NowTicks() + base::TimeDelta::FromDays(1); | |
41 } | |
42 | |
43 const url::Origin kOrigin_ = url::Origin(GURL("https://origin/")); | 25 const url::Origin kOrigin_ = url::Origin(GURL("https://origin/")); |
44 const GURL kEndpoint_ = GURL("https://endpoint/"); | 26 const GURL kEndpoint_ = GURL("https://endpoint/"); |
45 const std::string kGroup_ = "group"; | 27 const std::string kGroup_ = "group"; |
46 | |
47 base::SimpleTestTickClock clock_; | |
48 ReportingCache cache_; | |
49 BackoffEntry::Policy backoff_policy_; | |
50 ReportingEndpointManager manager_; | |
51 }; | 28 }; |
52 | 29 |
53 TEST_F(ReportingEndpointManagerTest, NoEndpoint) { | 30 TEST_F(ReportingEndpointManagerTest, NoEndpoint) { |
54 GURL endpoint_url; | 31 GURL endpoint_url; |
55 bool found_endpoint = | 32 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
56 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 33 kOrigin_, kGroup_, &endpoint_url); |
57 EXPECT_FALSE(found_endpoint); | 34 EXPECT_FALSE(found_endpoint); |
58 } | 35 } |
59 | 36 |
60 TEST_F(ReportingEndpointManagerTest, Endpoint) { | 37 TEST_F(ReportingEndpointManagerTest, Endpoint) { |
61 cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, | 38 cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, |
62 kGroup_, tomorrow()); | 39 kGroup_, tomorrow()); |
63 | 40 |
64 GURL endpoint_url; | 41 GURL endpoint_url; |
65 bool found_endpoint = | 42 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
66 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 43 kOrigin_, kGroup_, &endpoint_url); |
67 EXPECT_TRUE(found_endpoint); | 44 EXPECT_TRUE(found_endpoint); |
68 EXPECT_EQ(kEndpoint_, endpoint_url); | 45 EXPECT_EQ(kEndpoint_, endpoint_url); |
69 } | 46 } |
70 | 47 |
71 TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) { | 48 TEST_F(ReportingEndpointManagerTest, ExpiredEndpoint) { |
72 cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, | 49 cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, |
73 kGroup_, yesterday()); | 50 kGroup_, yesterday()); |
74 | 51 |
75 GURL endpoint_url; | 52 GURL endpoint_url; |
76 bool found_endpoint = | 53 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
77 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 54 kOrigin_, kGroup_, &endpoint_url); |
78 EXPECT_FALSE(found_endpoint); | 55 EXPECT_FALSE(found_endpoint); |
79 } | 56 } |
80 | 57 |
81 TEST_F(ReportingEndpointManagerTest, PendingEndpoint) { | 58 TEST_F(ReportingEndpointManagerTest, PendingEndpoint) { |
82 cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, | 59 cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, |
83 kGroup_, tomorrow()); | 60 kGroup_, tomorrow()); |
84 | 61 |
85 manager_.SetEndpointPending(kEndpoint_); | 62 endpoint_manager()->SetEndpointPending(kEndpoint_); |
86 | 63 |
87 GURL endpoint_url; | 64 GURL endpoint_url; |
88 bool found_endpoint = | 65 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
89 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 66 kOrigin_, kGroup_, &endpoint_url); |
90 EXPECT_FALSE(found_endpoint); | 67 EXPECT_FALSE(found_endpoint); |
91 | 68 |
92 manager_.ClearEndpointPending(kEndpoint_); | 69 endpoint_manager()->ClearEndpointPending(kEndpoint_); |
93 | 70 |
94 found_endpoint = | 71 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
95 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 72 kOrigin_, kGroup_, &endpoint_url); |
96 EXPECT_TRUE(found_endpoint); | 73 EXPECT_TRUE(found_endpoint); |
97 EXPECT_EQ(kEndpoint_, endpoint_url); | 74 EXPECT_EQ(kEndpoint_, endpoint_url); |
98 } | 75 } |
99 | 76 |
100 TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) { | 77 TEST_F(ReportingEndpointManagerTest, BackedOffEndpoint) { |
101 ASSERT_EQ(2.0, backoff_policy_.multiply_factor); | 78 ASSERT_EQ(2.0, policy().endpoint_backoff_policy.multiply_factor); |
102 | 79 |
103 cache_.SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, | 80 base::TimeDelta initial_delay = base::TimeDelta::FromMilliseconds( |
104 kGroup_, tomorrow()); | 81 policy().endpoint_backoff_policy.initial_delay_ms); |
105 | 82 |
106 manager_.InformOfEndpointRequest(kEndpoint_, false); | 83 cache()->SetClient(kOrigin_, kEndpoint_, ReportingClient::Subdomains::EXCLUDE, |
| 84 kGroup_, tomorrow()); |
| 85 |
| 86 endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); |
107 | 87 |
108 // After one failure, endpoint is in exponential backoff. | 88 // After one failure, endpoint is in exponential backoff. |
109 GURL endpoint_url; | 89 GURL endpoint_url; |
110 bool found_endpoint = | 90 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
111 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 91 kOrigin_, kGroup_, &endpoint_url); |
112 EXPECT_FALSE(found_endpoint); | 92 EXPECT_FALSE(found_endpoint); |
113 | 93 |
114 // After initial delay, endpoint is usable again. | 94 // After initial delay, endpoint is usable again. |
115 clock_.Advance( | 95 tick_clock()->Advance(initial_delay); |
116 base::TimeDelta::FromMilliseconds(backoff_policy_.initial_delay_ms)); | |
117 | 96 |
118 found_endpoint = | 97 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
119 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 98 kOrigin_, kGroup_, &endpoint_url); |
120 EXPECT_TRUE(found_endpoint); | 99 EXPECT_TRUE(found_endpoint); |
121 EXPECT_EQ(kEndpoint_, endpoint_url); | 100 EXPECT_EQ(kEndpoint_, endpoint_url); |
122 | 101 |
123 manager_.InformOfEndpointRequest(kEndpoint_, false); | 102 endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); |
124 | 103 |
125 // After a second failure, endpoint is backed off again. | 104 // After a second failure, endpoint is backed off again. |
126 found_endpoint = | 105 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
127 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 106 kOrigin_, kGroup_, &endpoint_url); |
128 EXPECT_FALSE(found_endpoint); | 107 EXPECT_FALSE(found_endpoint); |
129 | 108 |
130 clock_.Advance( | 109 tick_clock()->Advance(initial_delay); |
131 base::TimeDelta::FromMilliseconds(backoff_policy_.initial_delay_ms)); | |
132 | 110 |
133 // Next backoff is longer -- 2x the first -- so endpoint isn't usable yet. | 111 // Next backoff is longer -- 2x the first -- so endpoint isn't usable yet. |
134 found_endpoint = | 112 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
135 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 113 kOrigin_, kGroup_, &endpoint_url); |
136 EXPECT_FALSE(found_endpoint); | 114 EXPECT_FALSE(found_endpoint); |
137 | 115 |
138 clock_.Advance( | 116 tick_clock()->Advance(initial_delay); |
139 base::TimeDelta::FromMilliseconds(backoff_policy_.initial_delay_ms)); | |
140 | 117 |
141 // After 2x the initial delay, the endpoint is usable again. | 118 // After 2x the initial delay, the endpoint is usable again. |
142 found_endpoint = | 119 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
143 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 120 kOrigin_, kGroup_, &endpoint_url); |
144 EXPECT_TRUE(found_endpoint); | 121 EXPECT_TRUE(found_endpoint); |
145 EXPECT_EQ(kEndpoint_, endpoint_url); | 122 EXPECT_EQ(kEndpoint_, endpoint_url); |
146 | 123 |
147 manager_.InformOfEndpointRequest(kEndpoint_, true); | 124 endpoint_manager()->InformOfEndpointRequest(kEndpoint_, true); |
148 manager_.InformOfEndpointRequest(kEndpoint_, true); | 125 endpoint_manager()->InformOfEndpointRequest(kEndpoint_, true); |
149 | 126 |
150 // Two more successful requests should reset the backoff to the initial delay | 127 // Two more successful requests should reset the backoff to the initial delay |
151 // again. | 128 // again. |
152 manager_.InformOfEndpointRequest(kEndpoint_, false); | 129 endpoint_manager()->InformOfEndpointRequest(kEndpoint_, false); |
153 | 130 |
154 found_endpoint = | 131 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
155 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 132 kOrigin_, kGroup_, &endpoint_url); |
156 EXPECT_FALSE(found_endpoint); | 133 EXPECT_FALSE(found_endpoint); |
157 | 134 |
158 clock_.Advance( | 135 tick_clock()->Advance(initial_delay); |
159 base::TimeDelta::FromMilliseconds(backoff_policy_.initial_delay_ms)); | |
160 | 136 |
161 found_endpoint = | 137 found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
162 manager_.FindEndpointForOriginAndGroup(kOrigin_, kGroup_, &endpoint_url); | 138 kOrigin_, kGroup_, &endpoint_url); |
163 EXPECT_TRUE(found_endpoint); | 139 EXPECT_TRUE(found_endpoint); |
164 } | 140 } |
165 | 141 |
166 // Make sure that multiple endpoints will all be returned at some point, to | 142 // Make sure that multiple endpoints will all be returned at some point, to |
167 // avoid accidentally or intentionally implementing any priority ordering. | 143 // avoid accidentally or intentionally implementing any priority ordering. |
168 TEST_F(ReportingEndpointManagerTest, RandomEndpoint) { | 144 TEST_F(ReportingEndpointManagerTest, RandomEndpoint) { |
169 static const GURL kEndpoint1("https://endpoint1/"); | 145 static const GURL kEndpoint_1("https://endpoint1/"); |
170 static const GURL kEndpoint2("https://endpoint2/"); | 146 static const GURL kEndpoint_2("https://endpoint2/"); |
171 static const int kMaxAttempts = 20; | 147 static const int kMaxAttempts = 20; |
172 | 148 |
173 cache_.SetClient(kOrigin_, kEndpoint1, ReportingClient::Subdomains::EXCLUDE, | 149 cache()->SetClient(kOrigin_, kEndpoint_1, |
174 kGroup_, tomorrow()); | 150 ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); |
175 cache_.SetClient(kOrigin_, kEndpoint2, ReportingClient::Subdomains::EXCLUDE, | 151 cache()->SetClient(kOrigin_, kEndpoint_2, |
176 kGroup_, tomorrow()); | 152 ReportingClient::Subdomains::EXCLUDE, kGroup_, tomorrow()); |
177 | 153 |
178 bool endpoint1_seen = false; | 154 bool endpoint1_seen = false; |
179 bool endpoint2_seen = false; | 155 bool endpoint2_seen = false; |
180 | 156 |
181 for (int i = 0; i < kMaxAttempts; i++) { | 157 for (int i = 0; i < kMaxAttempts; i++) { |
182 GURL endpoint_url; | 158 GURL endpoint_url; |
183 bool found_endpoint = manager_.FindEndpointForOriginAndGroup( | 159 bool found_endpoint = endpoint_manager()->FindEndpointForOriginAndGroup( |
184 kOrigin_, kGroup_, &endpoint_url); | 160 kOrigin_, kGroup_, &endpoint_url); |
185 ASSERT_TRUE(found_endpoint); | 161 ASSERT_TRUE(found_endpoint); |
186 ASSERT_TRUE(endpoint_url == kEndpoint1 || endpoint_url == kEndpoint2); | 162 ASSERT_TRUE(endpoint_url == kEndpoint_1 || endpoint_url == kEndpoint_2); |
187 | 163 |
188 if (endpoint_url == kEndpoint1) | 164 if (endpoint_url == kEndpoint_1) |
189 endpoint1_seen = true; | 165 endpoint1_seen = true; |
190 else if (endpoint_url == kEndpoint2) | 166 else if (endpoint_url == kEndpoint_2) |
191 endpoint2_seen = true; | 167 endpoint2_seen = true; |
192 | 168 |
193 if (endpoint1_seen && endpoint2_seen) | 169 if (endpoint1_seen && endpoint2_seen) |
194 break; | 170 break; |
195 } | 171 } |
196 | 172 |
197 EXPECT_TRUE(endpoint1_seen); | 173 EXPECT_TRUE(endpoint1_seen); |
198 EXPECT_TRUE(endpoint2_seen); | 174 EXPECT_TRUE(endpoint2_seen); |
199 } | 175 } |
200 | 176 |
201 } // namespace | 177 } // namespace |
202 } // namespace net | 178 } // namespace net |
OLD | NEW |