OLD | NEW |
| (Empty) |
1 // Copyright 2016 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. | |
4 | |
5 #include "net/nqe/network_quality_observation.h" | |
6 | |
7 #include <stddef.h> | |
8 | |
9 #include <vector> | |
10 | |
11 #include "base/logging.h" | |
12 #include "base/macros.h" | |
13 #include "base/time/time.h" | |
14 #include "net/nqe/network_quality_observation_source.h" | |
15 #include "net/nqe/observation_buffer.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace net { | |
19 | |
20 namespace nqe { | |
21 | |
22 namespace { | |
23 | |
24 // Verifies that the percentiles are correctly computed. All observations have | |
25 // the same timestamp. | |
26 TEST(NetworkQualityObservationTest, PercentileSameTimestamps) { | |
27 internal::ObservationBuffer<int32_t> int_buffer(0.5); | |
28 internal::ObservationBuffer<base::TimeDelta> time_delta_buffer(0.5); | |
29 ASSERT_EQ(0u, int_buffer.Size()); | |
30 ASSERT_LT(0u, int_buffer.Capacity()); | |
31 ASSERT_EQ(0u, time_delta_buffer.Size()); | |
32 ASSERT_LT(0u, time_delta_buffer.Capacity()); | |
33 | |
34 const base::TimeTicks now = base::TimeTicks::Now(); | |
35 | |
36 int32_t result; | |
37 base::TimeDelta time_delta_result; | |
38 | |
39 // Percentiles should be unavailable when no observations are available. | |
40 EXPECT_FALSE( | |
41 int_buffer.GetPercentile(base::TimeTicks(), &result, 50, | |
42 std::vector<NetworkQualityObservationSource>())); | |
43 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
44 base::TimeTicks(), &time_delta_result, 50, | |
45 std::vector<NetworkQualityObservationSource>())); | |
46 | |
47 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even | |
48 // samples. This helps in verifying that the order of samples does not matter. | |
49 for (int i = 1; i <= 99; i += 2) { | |
50 int_buffer.AddObservation(internal::Observation<int32_t>( | |
51 i, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
52 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
53 base::TimeDelta::FromMilliseconds(i), now, | |
54 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
55 EXPECT_TRUE(int_buffer.GetPercentile( | |
56 base::TimeTicks(), &result, 50, | |
57 std::vector<NetworkQualityObservationSource>())); | |
58 ASSERT_EQ(static_cast<size_t>(i / 2 + 1), int_buffer.Size()); | |
59 EXPECT_TRUE(time_delta_buffer.GetPercentile( | |
60 base::TimeTicks(), &time_delta_result, 50, | |
61 std::vector<NetworkQualityObservationSource>())); | |
62 ASSERT_EQ(static_cast<size_t>(i / 2 + 1), time_delta_buffer.Size()); | |
63 } | |
64 | |
65 for (int i = 2; i <= 100; i += 2) { | |
66 int_buffer.AddObservation(internal::Observation<int32_t>( | |
67 i, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
68 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
69 base::TimeDelta::FromMilliseconds(i), now, | |
70 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
71 EXPECT_TRUE(int_buffer.GetPercentile( | |
72 base::TimeTicks(), &result, 50, | |
73 std::vector<NetworkQualityObservationSource>())); | |
74 ASSERT_EQ(static_cast<size_t>(i / 2 + 50), int_buffer.Size()); | |
75 EXPECT_TRUE(time_delta_buffer.GetPercentile( | |
76 base::TimeTicks(), &time_delta_result, 50, | |
77 std::vector<NetworkQualityObservationSource>())); | |
78 ASSERT_EQ(static_cast<size_t>(i / 2 + 50), time_delta_buffer.Size()); | |
79 } | |
80 | |
81 ASSERT_EQ(100u, int_buffer.Size()); | |
82 ASSERT_EQ(100u, time_delta_buffer.Size()); | |
83 | |
84 for (int i = 0; i <= 100; ++i) { | |
85 // Checks if the difference between the two integers is less than 1. This is | |
86 // required because computed percentiles may be slightly different from | |
87 // what is expected due to floating point computation errors and integer | |
88 // rounding off errors. | |
89 EXPECT_TRUE(int_buffer.GetPercentile( | |
90 base::TimeTicks(), &result, i, | |
91 std::vector<NetworkQualityObservationSource>())); | |
92 EXPECT_TRUE(time_delta_buffer.GetPercentile( | |
93 base::TimeTicks(), &time_delta_result, i, | |
94 std::vector<NetworkQualityObservationSource>())); | |
95 EXPECT_NEAR(result, i, 1); | |
96 EXPECT_NEAR(time_delta_result.InMilliseconds(), i, 1); | |
97 } | |
98 | |
99 EXPECT_FALSE(int_buffer.GetPercentile( | |
100 now + base::TimeDelta::FromSeconds(1), &result, 50, | |
101 std::vector<NetworkQualityObservationSource>())); | |
102 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
103 now + base::TimeDelta::FromSeconds(1), &time_delta_result, 50, | |
104 std::vector<NetworkQualityObservationSource>())); | |
105 | |
106 // Percentiles should be unavailable when no observations are available. | |
107 int_buffer.Clear(); | |
108 time_delta_buffer.Clear(); | |
109 EXPECT_FALSE( | |
110 int_buffer.GetPercentile(base::TimeTicks(), &result, 50, | |
111 std::vector<NetworkQualityObservationSource>())); | |
112 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
113 base::TimeTicks(), &time_delta_result, 50, | |
114 std::vector<NetworkQualityObservationSource>())); | |
115 } | |
116 | |
117 // Verifies that the percentiles are correctly computed. Observations have | |
118 // different timestamps with half the observations being very old and the rest | |
119 // of them being very recent. Percentiles should factor in recent observations | |
120 // much more heavily than older samples. | |
121 TEST(NetworkQualityObservationTest, PercentileDifferentTimestamps) { | |
122 internal::ObservationBuffer<int32_t> int_buffer(0.5); | |
123 internal::ObservationBuffer<base::TimeDelta> time_delta_buffer(0.5); | |
124 const base::TimeTicks now = base::TimeTicks::Now(); | |
125 const base::TimeTicks very_old = now - base::TimeDelta::FromDays(365); | |
126 | |
127 int32_t result; | |
128 base::TimeDelta time_delta_result; | |
129 | |
130 // Network quality should be unavailable when no observations are available. | |
131 EXPECT_FALSE( | |
132 int_buffer.GetPercentile(base::TimeTicks(), &result, 50, | |
133 std::vector<NetworkQualityObservationSource>())); | |
134 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
135 base::TimeTicks(), &time_delta_result, 50, | |
136 std::vector<NetworkQualityObservationSource>())); | |
137 | |
138 // First 50 samples have very old timestamp. | |
139 for (int i = 1; i <= 50; ++i) { | |
140 int_buffer.AddObservation(internal::Observation<int32_t>( | |
141 i, very_old, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
142 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
143 base::TimeDelta::FromMilliseconds(i), very_old, | |
144 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
145 } | |
146 | |
147 // Next 50 (i.e., from 51 to 100) have recent timestamp. | |
148 for (int i = 51; i <= 100; ++i) { | |
149 int_buffer.AddObservation(internal::Observation<int32_t>( | |
150 i, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
151 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
152 base::TimeDelta::FromMilliseconds(i), now, | |
153 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
154 } | |
155 | |
156 // Older samples have very little weight. So, all percentiles are >= 51 | |
157 // (lowest value among recent observations). | |
158 for (int i = 1; i < 100; ++i) { | |
159 // Checks if the difference between the two integers is less than 1. This is | |
160 // required because computed percentiles may be slightly different from | |
161 // what is expected due to floating point computation errors and integer | |
162 // rounding off errors. | |
163 EXPECT_TRUE(int_buffer.GetPercentile( | |
164 base::TimeTicks(), &result, i, | |
165 std::vector<NetworkQualityObservationSource>())); | |
166 EXPECT_NEAR(result, 51 + 0.49 * i, 1); | |
167 | |
168 EXPECT_TRUE(time_delta_buffer.GetPercentile( | |
169 base::TimeTicks(), &time_delta_result, i, | |
170 std::vector<NetworkQualityObservationSource>())); | |
171 EXPECT_NEAR(time_delta_result.InMilliseconds(), 51 + 0.49 * i, 1); | |
172 } | |
173 | |
174 EXPECT_FALSE(int_buffer.GetPercentile( | |
175 now + base::TimeDelta::FromSeconds(1), &result, 50, | |
176 std::vector<NetworkQualityObservationSource>())); | |
177 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
178 now + base::TimeDelta::FromSeconds(1), &time_delta_result, 50, | |
179 std::vector<NetworkQualityObservationSource>())); | |
180 } | |
181 | |
182 // Verifies that the percentiles are correctly computed when some of the | |
183 // observation sources are disallowed. All observations have the same timestamp. | |
184 TEST(NetworkQualityObservationTest, DisallowedObservationSources) { | |
185 internal::ObservationBuffer<int32_t> int_buffer(0.5); | |
186 internal::ObservationBuffer<base::TimeDelta> time_delta_buffer(0.5); | |
187 const base::TimeTicks now = base::TimeTicks::Now(); | |
188 | |
189 int32_t result; | |
190 base::TimeDelta time_delta_result; | |
191 | |
192 // Network quality should be unavailable when no observations are available. | |
193 EXPECT_FALSE( | |
194 int_buffer.GetPercentile(base::TimeTicks(), &result, 50, | |
195 std::vector<NetworkQualityObservationSource>())); | |
196 EXPECT_FALSE(time_delta_buffer.GetPercentile( | |
197 base::TimeTicks(), &time_delta_result, 50, | |
198 std::vector<NetworkQualityObservationSource>())); | |
199 | |
200 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even | |
201 // samples. This helps in verifying that the order of samples does not matter. | |
202 for (int i = 1; i <= 99; i += 2) { | |
203 int_buffer.AddObservation(internal::Observation<int32_t>( | |
204 i, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
205 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
206 base::TimeDelta::FromMilliseconds(i), now, | |
207 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
208 } | |
209 | |
210 // Add samples for TCP and QUIC observations which should not be taken into | |
211 // account when computing the percentile. | |
212 for (int i = 1; i <= 99; i += 2) { | |
213 int_buffer.AddObservation(internal::Observation<int32_t>( | |
214 10000, now, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP)); | |
215 int_buffer.AddObservation(internal::Observation<int32_t>( | |
216 10000, now, NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC)); | |
217 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
218 base::TimeDelta::FromMilliseconds(10000), now, | |
219 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP)); | |
220 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
221 base::TimeDelta::FromMilliseconds(10000), now, | |
222 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC)); | |
223 } | |
224 | |
225 for (int i = 2; i <= 100; i += 2) { | |
226 int_buffer.AddObservation(internal::Observation<int32_t>( | |
227 i, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
228 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
229 base::TimeDelta::FromMilliseconds(i), now, | |
230 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
231 } | |
232 | |
233 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | |
234 disallowed_observation_sources.push_back( | |
235 NETWORK_QUALITY_OBSERVATION_SOURCE_TCP); | |
236 disallowed_observation_sources.push_back( | |
237 NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC); | |
238 | |
239 for (int i = 0; i <= 100; ++i) { | |
240 // Checks if the difference between the two integers is less than 1. This is | |
241 // required because computed percentiles may be slightly different from | |
242 // what is expected due to floating point computation errors and integer | |
243 // rounding off errors. | |
244 EXPECT_TRUE(int_buffer.GetPercentile(base::TimeTicks(), &result, i, | |
245 disallowed_observation_sources)); | |
246 EXPECT_NEAR(result, i, 1); | |
247 EXPECT_TRUE( | |
248 time_delta_buffer.GetPercentile(base::TimeTicks(), &time_delta_result, | |
249 i, disallowed_observation_sources)); | |
250 EXPECT_NEAR(time_delta_result.InMilliseconds(), i, 1); | |
251 } | |
252 | |
253 // Now check the percentile value for TCP and QUIC observations. | |
254 disallowed_observation_sources.clear(); | |
255 disallowed_observation_sources.push_back( | |
256 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST); | |
257 for (int i = 0; i <= 100; ++i) { | |
258 // Checks if the difference between the two integers is less than 1. This is | |
259 // required because computed percentiles may be slightly different from | |
260 // what is expected due to floating point computation errors and integer | |
261 // rounding off errors. | |
262 EXPECT_TRUE(int_buffer.GetPercentile(base::TimeTicks(), &result, i, | |
263 disallowed_observation_sources)); | |
264 EXPECT_NEAR(result, 10000, 1); | |
265 EXPECT_TRUE( | |
266 time_delta_buffer.GetPercentile(base::TimeTicks(), &time_delta_result, | |
267 i, disallowed_observation_sources)); | |
268 EXPECT_NEAR(time_delta_result.InMilliseconds(), 10000, 1); | |
269 } | |
270 } | |
271 | |
272 TEST(NetworkQualityObservationTest, TestGetMedianRTTSince) { | |
273 internal::ObservationBuffer<int32_t> int_buffer(0.5); | |
274 internal::ObservationBuffer<base::TimeDelta> time_delta_buffer(0.5); | |
275 base::TimeTicks now = base::TimeTicks::Now(); | |
276 base::TimeTicks old = now - base::TimeDelta::FromMilliseconds(1); | |
277 ASSERT_NE(old, now); | |
278 | |
279 // First sample has very old timestamp. | |
280 int_buffer.AddObservation(internal::Observation<int32_t>( | |
281 1, old, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
282 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
283 base::TimeDelta::FromMilliseconds(1), old, | |
284 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
285 | |
286 int_buffer.AddObservation(internal::Observation<int32_t>( | |
287 100, now, NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
288 time_delta_buffer.AddObservation(internal::Observation<base::TimeDelta>( | |
289 base::TimeDelta::FromMilliseconds(100), now, | |
290 NETWORK_QUALITY_OBSERVATION_SOURCE_URL_REQUEST)); | |
291 | |
292 const struct { | |
293 base::TimeTicks start_timestamp; | |
294 bool expect_network_quality_available; | |
295 base::TimeDelta expected_url_request_rtt; | |
296 int32_t expected_downstream_throughput; | |
297 } tests[] = { | |
298 {now + base::TimeDelta::FromSeconds(10), false, | |
299 base::TimeDelta::FromMilliseconds(0), 0}, | |
300 {now, true, base::TimeDelta::FromMilliseconds(100), 100}, | |
301 {now - base::TimeDelta::FromMicroseconds(500), true, | |
302 base::TimeDelta::FromMilliseconds(100), 100}, | |
303 | |
304 }; | |
305 | |
306 for (const auto& test : tests) { | |
307 base::TimeDelta url_request_rtt; | |
308 int32_t downstream_throughput_kbps; | |
309 std::vector<NetworkQualityObservationSource> disallowed_observation_sources; | |
310 | |
311 EXPECT_EQ( | |
312 test.expect_network_quality_available, | |
313 time_delta_buffer.GetPercentile(test.start_timestamp, &url_request_rtt, | |
314 50, disallowed_observation_sources)); | |
315 EXPECT_EQ(test.expect_network_quality_available, | |
316 int_buffer.GetPercentile(test.start_timestamp, | |
317 &downstream_throughput_kbps, 50, | |
318 disallowed_observation_sources)); | |
319 | |
320 if (test.expect_network_quality_available) { | |
321 EXPECT_EQ(test.expected_url_request_rtt, url_request_rtt); | |
322 EXPECT_EQ(test.expected_downstream_throughput, | |
323 downstream_throughput_kbps); | |
324 } | |
325 } | |
326 } | |
327 | |
328 } // namespace | |
329 | |
330 } // namespace nqe | |
331 | |
332 } // namespace net | |
OLD | NEW |