xref: /aosp_15_r20/external/cronet/net/nqe/observation_buffer_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/nqe/observation_buffer.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <map>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <utility>
12*6777b538SAndroid Build Coastguard Worker #include <vector>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/test/simple_test_tick_clock.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
16*6777b538SAndroid Build Coastguard Worker #include "net/nqe/network_quality_estimator_params.h"
17*6777b538SAndroid Build Coastguard Worker #include "net/nqe/network_quality_observation.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/nqe/network_quality_observation_source.h"
19*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker namespace net::nqe::internal {
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker namespace {
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker // Verify that the buffer size is never exceeded.
TEST(NetworkQualityObservationBufferTest,BoundedBuffer)26*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, BoundedBuffer) {
27*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
28*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
29*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
30*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
31*6777b538SAndroid Build Coastguard Worker   ObservationBuffer observation_buffer(&params, &tick_clock, 1.0, 1.0);
32*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = base::TimeTicks() + base::Seconds(1);
33*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 1000; ++i) {
34*6777b538SAndroid Build Coastguard Worker     observation_buffer.AddObservation(
35*6777b538SAndroid Build Coastguard Worker         Observation(i, now, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_TCP));
36*6777b538SAndroid Build Coastguard Worker     // The number of entries should be at most the maximum buffer size.
37*6777b538SAndroid Build Coastguard Worker     EXPECT_GE(300u, observation_buffer.Size());
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker 
41*6777b538SAndroid Build Coastguard Worker // Verify that the percentiles are monotonically non-decreasing when a weight is
42*6777b538SAndroid Build Coastguard Worker // applied.
TEST(NetworkQualityObservationBufferTest,GetPercentileWithWeights)43*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, GetPercentileWithWeights) {
44*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
45*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
46*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
47*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker   ObservationBuffer observation_buffer(&params, &tick_clock, 0.98, 1.0);
50*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = tick_clock.NowTicks();
51*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 100; ++i) {
52*6777b538SAndroid Build Coastguard Worker     tick_clock.Advance(base::Seconds(1));
53*6777b538SAndroid Build Coastguard Worker     observation_buffer.AddObservation(
54*6777b538SAndroid Build Coastguard Worker         Observation(i, tick_clock.NowTicks(), INT32_MIN,
55*6777b538SAndroid Build Coastguard Worker                     NETWORK_QUALITY_OBSERVATION_SOURCE_TCP));
56*6777b538SAndroid Build Coastguard Worker   }
57*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100U, observation_buffer.Size());
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker   int32_t result_lowest = INT32_MAX;
60*6777b538SAndroid Build Coastguard Worker   int32_t result_highest = INT32_MIN;
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 100; ++i) {
63*6777b538SAndroid Build Coastguard Worker     size_t observations_count = 0;
64*6777b538SAndroid Build Coastguard Worker     // Verify that i'th percentile is more than i-1'th percentile.
65*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result_i = observation_buffer.GetPercentile(
66*6777b538SAndroid Build Coastguard Worker         now, INT32_MIN, i, &observations_count);
67*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(100u, observations_count);
68*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(result_i.has_value());
69*6777b538SAndroid Build Coastguard Worker     result_lowest = std::min(result_lowest, result_i.value());
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker     result_highest = std::max(result_highest, result_i.value());
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result_i_1 = observation_buffer.GetPercentile(
74*6777b538SAndroid Build Coastguard Worker         now, INT32_MIN, i - 1, &observations_count);
75*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(100u, observations_count);
76*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(result_i_1.has_value());
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(result_i_1.value(), result_i.value());
79*6777b538SAndroid Build Coastguard Worker   }
80*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(result_lowest, result_highest);
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker 
83*6777b538SAndroid Build Coastguard Worker // Verifies that the percentiles are correctly computed. All observations have
84*6777b538SAndroid Build Coastguard Worker // the same timestamp.
TEST(NetworkQualityObservationBufferTest,PercentileSameTimestamps)85*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, PercentileSameTimestamps) {
86*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
87*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
88*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
89*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
90*6777b538SAndroid Build Coastguard Worker   ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
91*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, buffer.Size());
92*6777b538SAndroid Build Coastguard Worker   ASSERT_LT(0u, buffer.Capacity());
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = tick_clock.NowTicks();
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   size_t observations_count = 0;
97*6777b538SAndroid Build Coastguard Worker   // Percentiles should be unavailable when no observations are available.
98*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
99*6777b538SAndroid Build Coastguard Worker       buffer
100*6777b538SAndroid Build Coastguard Worker           .GetPercentile(base::TimeTicks(), INT32_MIN, 50,
101*6777b538SAndroid Build Coastguard Worker                          &observations_count)
102*6777b538SAndroid Build Coastguard Worker           .has_value());
103*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, observations_count);
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker   // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even
106*6777b538SAndroid Build Coastguard Worker   // samples. This helps in verifying that the order of samples does not matter.
107*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 99; i += 2) {
108*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, INT32_MIN,
109*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
110*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr)
111*6777b538SAndroid Build Coastguard Worker                     .has_value());
112*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<size_t>(i / 2 + 1), buffer.Size());
113*6777b538SAndroid Build Coastguard Worker   }
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   for (int i = 2; i <= 100; i += 2) {
116*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, INT32_MIN,
117*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
118*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr)
119*6777b538SAndroid Build Coastguard Worker                     .has_value());
120*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<size_t>(i / 2 + 50), buffer.Size());
121*6777b538SAndroid Build Coastguard Worker   }
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(100u, buffer.Size());
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i <= 100; ++i) {
126*6777b538SAndroid Build Coastguard Worker     // Checks if the difference between actual result and the computed result is
127*6777b538SAndroid Build Coastguard Worker     // less than 1. This is required because computed percentiles may be
128*6777b538SAndroid Build Coastguard Worker     // slightly different from what is expected due to floating point
129*6777b538SAndroid Build Coastguard Worker     // computation errors and integer rounding off errors.
130*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result = buffer.GetPercentile(
131*6777b538SAndroid Build Coastguard Worker         base::TimeTicks(), INT32_MIN, i, &observations_count);
132*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(100u, observations_count);
133*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(result.has_value());
134*6777b538SAndroid Build Coastguard Worker     EXPECT_NEAR(result.value(), i, 1.0);
135*6777b538SAndroid Build Coastguard Worker   }
136*6777b538SAndroid Build Coastguard Worker 
137*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(buffer
138*6777b538SAndroid Build Coastguard Worker                    .GetPercentile(now + base::Seconds(1), INT32_MIN, 50,
139*6777b538SAndroid Build Coastguard Worker                                   &observations_count)
140*6777b538SAndroid Build Coastguard Worker                    .has_value());
141*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, observations_count);
142*6777b538SAndroid Build Coastguard Worker 
143*6777b538SAndroid Build Coastguard Worker   // Percentiles should be unavailable when no observations are available.
144*6777b538SAndroid Build Coastguard Worker   buffer.Clear();
145*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
146*6777b538SAndroid Build Coastguard Worker       buffer
147*6777b538SAndroid Build Coastguard Worker           .GetPercentile(base::TimeTicks(), INT32_MIN, 50,
148*6777b538SAndroid Build Coastguard Worker                          &observations_count)
149*6777b538SAndroid Build Coastguard Worker           .has_value());
150*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, observations_count);
151*6777b538SAndroid Build Coastguard Worker }
152*6777b538SAndroid Build Coastguard Worker 
153*6777b538SAndroid Build Coastguard Worker // Verifies that the percentiles are correctly computed. Observations have
154*6777b538SAndroid Build Coastguard Worker // different timestamps with half the observations being very old and the rest
155*6777b538SAndroid Build Coastguard Worker // of them being very recent. Percentiles should factor in recent observations
156*6777b538SAndroid Build Coastguard Worker // much more heavily than older samples.
TEST(NetworkQualityObservationBufferTest,PercentileDifferentTimestamps)157*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, PercentileDifferentTimestamps) {
158*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
159*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
160*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
161*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
162*6777b538SAndroid Build Coastguard Worker   ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
163*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = tick_clock.NowTicks();
164*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks very_old = now - base::Days(7);
165*6777b538SAndroid Build Coastguard Worker 
166*6777b538SAndroid Build Coastguard Worker   size_t observations_count;
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker   // Network quality should be unavailable when no observations are available.
169*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
170*6777b538SAndroid Build Coastguard Worker       buffer
171*6777b538SAndroid Build Coastguard Worker           .GetPercentile(base::TimeTicks(), INT32_MIN, 50,
172*6777b538SAndroid Build Coastguard Worker                          &observations_count)
173*6777b538SAndroid Build Coastguard Worker           .has_value());
174*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, observations_count);
175*6777b538SAndroid Build Coastguard Worker 
176*6777b538SAndroid Build Coastguard Worker   // First 50 samples have very old timestamps.
177*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 50; ++i) {
178*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, very_old, INT32_MIN,
179*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
180*6777b538SAndroid Build Coastguard Worker   }
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   // Next 50 (i.e., from 51 to 100) have recent timestamps.
183*6777b538SAndroid Build Coastguard Worker   for (int i = 51; i <= 100; ++i) {
184*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, INT32_MIN,
185*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
186*6777b538SAndroid Build Coastguard Worker   }
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   // Older samples have very little weight. So, all percentiles are >= 51
189*6777b538SAndroid Build Coastguard Worker   // (lowest value among recent observations).
190*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < 100; ++i) {
191*6777b538SAndroid Build Coastguard Worker     // Checks if the difference between the two integers is less than 1. This is
192*6777b538SAndroid Build Coastguard Worker     // required because computed percentiles may be slightly different from
193*6777b538SAndroid Build Coastguard Worker     // what is expected due to floating point computation errors and integer
194*6777b538SAndroid Build Coastguard Worker     // rounding off errors.
195*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result =
196*6777b538SAndroid Build Coastguard Worker         buffer.GetPercentile(very_old, INT32_MIN, i, &observations_count);
197*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(result.has_value());
198*6777b538SAndroid Build Coastguard Worker     EXPECT_NEAR(result.value(), 51 + 0.49 * i, 1);
199*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(100u, observations_count);
200*6777b538SAndroid Build Coastguard Worker   }
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(buffer.GetPercentile(now + base::Seconds(1), INT32_MIN, 50,
203*6777b538SAndroid Build Coastguard Worker                                     &observations_count));
204*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, observations_count);
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker // Verifies that the percentiles are correctly computed. All observations have
208*6777b538SAndroid Build Coastguard Worker // same timestamp with half the observations taken at low RSSI, and half the
209*6777b538SAndroid Build Coastguard Worker // observations with high RSSI. Percentiles should be computed based on the
210*6777b538SAndroid Build Coastguard Worker // current RSSI and the RSSI of the observations.
TEST(NetworkQualityObservationBufferTest,PercentileDifferentRSSI)211*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, PercentileDifferentRSSI) {
212*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
213*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
214*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
215*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
216*6777b538SAndroid Build Coastguard Worker   ObservationBuffer buffer(&params, &tick_clock, 1.0, 0.25);
217*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = tick_clock.NowTicks();
218*6777b538SAndroid Build Coastguard Worker   int32_t high_rssi = 4;
219*6777b538SAndroid Build Coastguard Worker   int32_t low_rssi = 0;
220*6777b538SAndroid Build Coastguard Worker 
221*6777b538SAndroid Build Coastguard Worker   // Network quality should be unavailable when no observations are available.
222*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(buffer.GetPercentile(base::TimeTicks(), INT32_MIN, 50, nullptr)
223*6777b538SAndroid Build Coastguard Worker                    .has_value());
224*6777b538SAndroid Build Coastguard Worker 
225*6777b538SAndroid Build Coastguard Worker   // First 50 samples have very low RSSI.
226*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 50; ++i) {
227*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(
228*6777b538SAndroid Build Coastguard Worker         Observation(i, now, low_rssi, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
229*6777b538SAndroid Build Coastguard Worker   }
230*6777b538SAndroid Build Coastguard Worker 
231*6777b538SAndroid Build Coastguard Worker   // Next 50 (i.e., from 51 to 100) have high RSSI.
232*6777b538SAndroid Build Coastguard Worker   for (int i = 51; i <= 100; ++i) {
233*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, high_rssi,
234*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
235*6777b538SAndroid Build Coastguard Worker   }
236*6777b538SAndroid Build Coastguard Worker 
237*6777b538SAndroid Build Coastguard Worker   // When the current RSSI is |high_rssi|, higher weight should be assigned
238*6777b538SAndroid Build Coastguard Worker   // to observations that were taken at |high_rssi|.
239*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < 100; ++i) {
240*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result =
241*6777b538SAndroid Build Coastguard Worker         buffer.GetPercentile(now, high_rssi, i, nullptr);
242*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(result.has_value());
243*6777b538SAndroid Build Coastguard Worker     EXPECT_NEAR(result.value(), 51 + 0.49 * i, 2);
244*6777b538SAndroid Build Coastguard Worker   }
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   // When the current RSSI is |low_rssi|, higher weight should be assigned
247*6777b538SAndroid Build Coastguard Worker   // to observations that were taken at |low_rssi|.
248*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i < 100; ++i) {
249*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result =
250*6777b538SAndroid Build Coastguard Worker         buffer.GetPercentile(now, low_rssi, i, nullptr);
251*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(result.has_value());
252*6777b538SAndroid Build Coastguard Worker     EXPECT_NEAR(result.value(), i / 2, 2);
253*6777b538SAndroid Build Coastguard Worker   }
254*6777b538SAndroid Build Coastguard Worker }
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker // Verifies that the percentiles are correctly computed when some of the
257*6777b538SAndroid Build Coastguard Worker // observation sources are disallowed. All observations have the same timestamp.
TEST(NetworkQualityObservationBufferTest,RemoveObservations)258*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, RemoveObservations) {
259*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
260*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
261*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
262*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
263*6777b538SAndroid Build Coastguard Worker 
264*6777b538SAndroid Build Coastguard Worker   ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
265*6777b538SAndroid Build Coastguard Worker   const base::TimeTicks now = tick_clock.NowTicks();
266*6777b538SAndroid Build Coastguard Worker 
267*6777b538SAndroid Build Coastguard Worker   // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even
268*6777b538SAndroid Build Coastguard Worker   // samples. This helps in verifying that the order of samples does not matter.
269*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 99; i += 2) {
270*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, INT32_MIN,
271*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
272*6777b538SAndroid Build Coastguard Worker   }
273*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(50u, buffer.Size());
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   // Add samples for TCP and QUIC observations which should not be taken into
276*6777b538SAndroid Build Coastguard Worker   // account when computing the percentile.
277*6777b538SAndroid Build Coastguard Worker   for (int i = 1; i <= 99; i += 2) {
278*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(10000, now, INT32_MIN,
279*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_TCP));
280*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(10000, now, INT32_MIN,
281*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC));
282*6777b538SAndroid Build Coastguard Worker   }
283*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(150u, buffer.Size());
284*6777b538SAndroid Build Coastguard Worker 
285*6777b538SAndroid Build Coastguard Worker   for (int i = 2; i <= 100; i += 2) {
286*6777b538SAndroid Build Coastguard Worker     buffer.AddObservation(Observation(i, now, INT32_MIN,
287*6777b538SAndroid Build Coastguard Worker                                       NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
288*6777b538SAndroid Build Coastguard Worker   }
289*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200u, buffer.Size());
290*6777b538SAndroid Build Coastguard Worker 
291*6777b538SAndroid Build Coastguard Worker   bool deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_MAX] = {
292*6777b538SAndroid Build Coastguard Worker       false};
293*6777b538SAndroid Build Coastguard Worker 
294*6777b538SAndroid Build Coastguard Worker   // Since all entries in |deleted_observation_sources| are set to false, no
295*6777b538SAndroid Build Coastguard Worker   // observations should be deleted.
296*6777b538SAndroid Build Coastguard Worker   buffer.RemoveObservationsWithSource(deleted_observation_sources);
297*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(200u, buffer.Size());
298*6777b538SAndroid Build Coastguard Worker 
299*6777b538SAndroid Build Coastguard Worker   // 50 TCP and 50 QUIC observations should be deleted.
300*6777b538SAndroid Build Coastguard Worker   deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_TCP] = true;
301*6777b538SAndroid Build Coastguard Worker   deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_QUIC] = true;
302*6777b538SAndroid Build Coastguard Worker   buffer.RemoveObservationsWithSource(deleted_observation_sources);
303*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(100u, buffer.Size());
304*6777b538SAndroid Build Coastguard Worker 
305*6777b538SAndroid Build Coastguard Worker   for (int i = 0; i <= 100; ++i) {
306*6777b538SAndroid Build Coastguard Worker     // Checks if the difference between the two integers is less than 1. This is
307*6777b538SAndroid Build Coastguard Worker     // required because computed percentiles may be slightly different from
308*6777b538SAndroid Build Coastguard Worker     // what is expected due to floating point computation errors and integer
309*6777b538SAndroid Build Coastguard Worker     // rounding off errors.
310*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> result =
311*6777b538SAndroid Build Coastguard Worker         buffer.GetPercentile(base::TimeTicks(), INT32_MIN, i, nullptr);
312*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(result.has_value());
313*6777b538SAndroid Build Coastguard Worker     EXPECT_NEAR(result.value(), i, 1);
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker 
316*6777b538SAndroid Build Coastguard Worker   deleted_observation_sources[NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP] = true;
317*6777b538SAndroid Build Coastguard Worker   buffer.RemoveObservationsWithSource(deleted_observation_sources);
318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0u, buffer.Size());
319*6777b538SAndroid Build Coastguard Worker }
320*6777b538SAndroid Build Coastguard Worker 
TEST(NetworkQualityObservationBufferTest,TestGetMedianRTTSince)321*6777b538SAndroid Build Coastguard Worker TEST(NetworkQualityObservationBufferTest, TestGetMedianRTTSince) {
322*6777b538SAndroid Build Coastguard Worker   std::map<std::string, std::string> variation_params;
323*6777b538SAndroid Build Coastguard Worker   NetworkQualityEstimatorParams params(variation_params);
324*6777b538SAndroid Build Coastguard Worker   base::SimpleTestTickClock tick_clock;
325*6777b538SAndroid Build Coastguard Worker   tick_clock.Advance(base::Minutes(1));
326*6777b538SAndroid Build Coastguard Worker   ObservationBuffer buffer(&params, &tick_clock, 0.5, 1.0);
327*6777b538SAndroid Build Coastguard Worker   base::TimeTicks now = tick_clock.NowTicks();
328*6777b538SAndroid Build Coastguard Worker   base::TimeTicks old = now - base::Milliseconds(1);
329*6777b538SAndroid Build Coastguard Worker   ASSERT_NE(old, now);
330*6777b538SAndroid Build Coastguard Worker 
331*6777b538SAndroid Build Coastguard Worker   // First sample has very old timestamp.
332*6777b538SAndroid Build Coastguard Worker   buffer.AddObservation(
333*6777b538SAndroid Build Coastguard Worker       Observation(1, old, INT32_MIN, NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
334*6777b538SAndroid Build Coastguard Worker 
335*6777b538SAndroid Build Coastguard Worker   buffer.AddObservation(Observation(100, now, INT32_MIN,
336*6777b538SAndroid Build Coastguard Worker                                     NETWORK_QUALITY_OBSERVATION_SOURCE_HTTP));
337*6777b538SAndroid Build Coastguard Worker 
338*6777b538SAndroid Build Coastguard Worker   const struct {
339*6777b538SAndroid Build Coastguard Worker     base::TimeTicks start_timestamp;
340*6777b538SAndroid Build Coastguard Worker     bool expect_network_quality_available;
341*6777b538SAndroid Build Coastguard Worker     base::TimeDelta expected_url_request_rtt;
342*6777b538SAndroid Build Coastguard Worker   } tests[] = {
343*6777b538SAndroid Build Coastguard Worker       {now + base::Seconds(10), false, base::Milliseconds(0)},
344*6777b538SAndroid Build Coastguard Worker       {now, true, base::Milliseconds(100)},
345*6777b538SAndroid Build Coastguard Worker       {now - base::Microseconds(500), true, base::Milliseconds(100)},
346*6777b538SAndroid Build Coastguard Worker 
347*6777b538SAndroid Build Coastguard Worker   };
348*6777b538SAndroid Build Coastguard Worker 
349*6777b538SAndroid Build Coastguard Worker   for (const auto& test : tests) {
350*6777b538SAndroid Build Coastguard Worker     std::optional<int32_t> url_request_rtt =
351*6777b538SAndroid Build Coastguard Worker         buffer.GetPercentile(test.start_timestamp, INT32_MIN, 50, nullptr);
352*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.expect_network_quality_available,
353*6777b538SAndroid Build Coastguard Worker               url_request_rtt.has_value());
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker     if (test.expect_network_quality_available) {
356*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test.expected_url_request_rtt.InMillisecondsF(),
357*6777b538SAndroid Build Coastguard Worker                 url_request_rtt.value());
358*6777b538SAndroid Build Coastguard Worker     }
359*6777b538SAndroid Build Coastguard Worker   }
360*6777b538SAndroid Build Coastguard Worker }
361*6777b538SAndroid Build Coastguard Worker 
362*6777b538SAndroid Build Coastguard Worker 
363*6777b538SAndroid Build Coastguard Worker }  // namespace
364*6777b538SAndroid Build Coastguard Worker 
365*6777b538SAndroid Build Coastguard Worker }  // namespace net::nqe::internal
366