xref: /aosp_15_r20/external/cronet/net/nqe/network_quality_store_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2016 The Chromium Authors
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_store.h"
6 
7 #include "base/strings/string_number_conversions.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "base/time/time.h"
10 #include "net/base/network_change_notifier.h"
11 #include "net/nqe/cached_network_quality.h"
12 #include "net/nqe/effective_connection_type.h"
13 #include "net/nqe/network_id.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace net {
17 
18 namespace {
19 
TEST(NetworkQualityStoreTest,TestCaching)20 TEST(NetworkQualityStoreTest, TestCaching) {
21   nqe::internal::NetworkQualityStore network_quality_store;
22   base::SimpleTestTickClock tick_clock;
23 
24   // Cached network quality for network with NetworkID (2G, "test1").
25   const nqe::internal::CachedNetworkQuality cached_network_quality_2g_test1(
26       tick_clock.NowTicks(),
27       nqe::internal::NetworkQuality(base::Seconds(1), base::Seconds(1), 1),
28       EFFECTIVE_CONNECTION_TYPE_2G);
29 
30   {
31     // When ECT is UNKNOWN, then the network quality is not cached.
32     nqe::internal::CachedNetworkQuality cached_network_quality_unknown(
33         tick_clock.NowTicks(),
34         nqe::internal::NetworkQuality(base::Seconds(1), base::Seconds(1), 1),
35         EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
36 
37     // Entry should not be added.
38     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
39                                         "test1", 0);
40     nqe::internal::CachedNetworkQuality read_network_quality;
41     network_quality_store.Add(network_id, cached_network_quality_unknown);
42     EXPECT_FALSE(
43         network_quality_store.GetById(network_id, &read_network_quality));
44   }
45 
46   {
47     // Entry will be added for (2G, "test1").
48     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
49                                         "test1", 0);
50     nqe::internal::CachedNetworkQuality read_network_quality;
51     network_quality_store.Add(network_id, cached_network_quality_2g_test1);
52     EXPECT_TRUE(
53         network_quality_store.GetById(network_id, &read_network_quality));
54     EXPECT_EQ(cached_network_quality_2g_test1.network_quality(),
55               read_network_quality.network_quality());
56   }
57 
58   {
59     // Entry will be added for (2G, "test2").
60     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
61                                         "test2", 0);
62     nqe::internal::CachedNetworkQuality read_network_quality;
63     nqe::internal::CachedNetworkQuality cached_network_quality(
64         tick_clock.NowTicks(),
65         nqe::internal::NetworkQuality(base::Seconds(2), base::Seconds(2), 2),
66         EFFECTIVE_CONNECTION_TYPE_2G);
67     network_quality_store.Add(network_id, cached_network_quality);
68     EXPECT_TRUE(
69         network_quality_store.GetById(network_id, &read_network_quality));
70     EXPECT_EQ(read_network_quality.network_quality(),
71               cached_network_quality.network_quality());
72   }
73 
74   {
75     // Entry will be added for (3G, "test3").
76     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_3G,
77                                         "test3", 0);
78     nqe::internal::CachedNetworkQuality read_network_quality;
79     nqe::internal::CachedNetworkQuality cached_network_quality(
80         tick_clock.NowTicks(),
81         nqe::internal::NetworkQuality(base::Seconds(3), base::Seconds(3), 3),
82         EFFECTIVE_CONNECTION_TYPE_3G);
83     network_quality_store.Add(network_id, cached_network_quality);
84     EXPECT_TRUE(
85         network_quality_store.GetById(network_id, &read_network_quality));
86     EXPECT_EQ(read_network_quality.network_quality(),
87               cached_network_quality.network_quality());
88   }
89 
90   {
91     // Entry will be added for (Unknown, "").
92     nqe::internal::NetworkID network_id(
93         NetworkChangeNotifier::CONNECTION_UNKNOWN, "", 0);
94     nqe::internal::CachedNetworkQuality read_network_quality;
95     nqe::internal::CachedNetworkQuality set_network_quality(
96         tick_clock.NowTicks(),
97         nqe::internal::NetworkQuality(base::Seconds(4), base::Seconds(4), 4),
98         EFFECTIVE_CONNECTION_TYPE_4G);
99     network_quality_store.Add(network_id, set_network_quality);
100     EXPECT_TRUE(
101         network_quality_store.GetById(network_id, &read_network_quality));
102   }
103 
104   {
105     // Existing entry will be read for (2G, "test1").
106     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
107                                         "test1", 0);
108     nqe::internal::CachedNetworkQuality read_network_quality;
109     EXPECT_TRUE(
110         network_quality_store.GetById(network_id, &read_network_quality));
111     EXPECT_EQ(cached_network_quality_2g_test1.network_quality(),
112               read_network_quality.network_quality());
113   }
114 
115   {
116     // Existing entry will be overwritten for (2G, "test1").
117     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
118                                         "test1", 0);
119     nqe::internal::CachedNetworkQuality read_network_quality;
120     const nqe::internal::CachedNetworkQuality cached_network_quality(
121         tick_clock.NowTicks(),
122         nqe::internal::NetworkQuality(base::Seconds(5), base::Seconds(5), 5),
123         EFFECTIVE_CONNECTION_TYPE_4G);
124     network_quality_store.Add(network_id, cached_network_quality);
125     EXPECT_TRUE(
126         network_quality_store.GetById(network_id, &read_network_quality));
127     EXPECT_EQ(cached_network_quality.network_quality(),
128               read_network_quality.network_quality());
129   }
130 
131   {
132     // No entry should exist for (2G, "test4").
133     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
134                                         "test4", 0);
135     nqe::internal::CachedNetworkQuality read_network_quality;
136     EXPECT_FALSE(
137         network_quality_store.GetById(network_id, &read_network_quality));
138   }
139 }
140 
TEST(NetworkQualityStoreTest,TestCachingClosestSignalStrength)141 TEST(NetworkQualityStoreTest, TestCachingClosestSignalStrength) {
142   nqe::internal::NetworkQualityStore network_quality_store;
143   base::SimpleTestTickClock tick_clock;
144 
145   // Cached network quality for network with NetworkID (2G, "test1").
146   const nqe::internal::CachedNetworkQuality cached_network_quality_strength_1(
147       tick_clock.NowTicks(),
148       nqe::internal::NetworkQuality(base::Seconds(1), base::Seconds(1), 1),
149       EFFECTIVE_CONNECTION_TYPE_2G);
150 
151   const nqe::internal::CachedNetworkQuality cached_network_quality_strength_3(
152       tick_clock.NowTicks(),
153       nqe::internal::NetworkQuality(base::Seconds(3), base::Seconds(3), 3),
154       EFFECTIVE_CONNECTION_TYPE_2G);
155 
156   {
157     // Entry will be added for (2G, "test1") with signal strength value of 1.
158     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
159                                         "test1", 1);
160     nqe::internal::CachedNetworkQuality read_network_quality;
161     network_quality_store.Add(network_id, cached_network_quality_strength_1);
162     EXPECT_TRUE(
163         network_quality_store.GetById(network_id, &read_network_quality));
164     EXPECT_EQ(cached_network_quality_strength_1.network_quality(),
165               read_network_quality.network_quality());
166   }
167 
168   {
169     // Entry will be added for (2G, "test1") with signal strength value of 3.
170     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
171                                         "test1", 3);
172     nqe::internal::CachedNetworkQuality read_network_quality;
173     network_quality_store.Add(network_id, cached_network_quality_strength_3);
174     EXPECT_TRUE(
175         network_quality_store.GetById(network_id, &read_network_quality));
176     EXPECT_EQ(cached_network_quality_strength_3.network_quality(),
177               read_network_quality.network_quality());
178   }
179 
180   {
181     // Now with cached entries for signal strengths 1 and 3, verify across the
182     // range of strength values that the closest value match will be returned
183     // when looking up (2G, "test1", signal_strength).
184     for (int32_t signal_strength = 0; signal_strength <= 4; ++signal_strength) {
185       nqe::internal::CachedNetworkQuality expected_cached_network_quality =
186           signal_strength <= 2 ? cached_network_quality_strength_1
187                                : cached_network_quality_strength_3;
188       nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
189                                           "test1", signal_strength);
190       nqe::internal::CachedNetworkQuality read_network_quality;
191       EXPECT_TRUE(
192           network_quality_store.GetById(network_id, &read_network_quality));
193       EXPECT_EQ(expected_cached_network_quality.network_quality(),
194                 read_network_quality.network_quality());
195     }
196   }
197 
198   {
199     // When the current network does not have signal strength available, then
200     // the cached value that corresponds to maximum signal strength should be
201     // returned.
202     int32_t signal_strength = INT32_MIN;
203     nqe::internal::CachedNetworkQuality expected_cached_network_quality =
204         cached_network_quality_strength_3;
205     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
206                                         "test1", signal_strength);
207     nqe::internal::CachedNetworkQuality read_network_quality;
208     EXPECT_TRUE(
209         network_quality_store.GetById(network_id, &read_network_quality));
210     EXPECT_EQ(expected_cached_network_quality.network_quality(),
211               read_network_quality.network_quality());
212   }
213 
214   {
215     // No entry should exist for (2G, "test4").
216     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
217                                         "test4", 0);
218     nqe::internal::CachedNetworkQuality read_network_quality;
219     EXPECT_FALSE(
220         network_quality_store.GetById(network_id, &read_network_quality));
221   }
222 }
223 
TEST(NetworkQualityStoreTest,TestCachingUnknownSignalStrength)224 TEST(NetworkQualityStoreTest, TestCachingUnknownSignalStrength) {
225   nqe::internal::NetworkQualityStore network_quality_store;
226   base::SimpleTestTickClock tick_clock;
227 
228   // Cached network quality for network with NetworkID (2G, "test1").
229   const nqe::internal::CachedNetworkQuality
230       cached_network_quality_strength_unknown(
231           tick_clock.NowTicks(),
232           nqe::internal::NetworkQuality(base::Seconds(1), base::Seconds(1), 1),
233           EFFECTIVE_CONNECTION_TYPE_2G);
234 
235   const nqe::internal::CachedNetworkQuality cached_network_quality_strength_3(
236       tick_clock.NowTicks(),
237       nqe::internal::NetworkQuality(base::Seconds(3), base::Seconds(3), 3),
238       EFFECTIVE_CONNECTION_TYPE_2G);
239 
240   {
241     // Entry will be added for (2G, "test1") with signal strength value of
242     // INT32_MIN.
243     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
244                                         "test1", INT32_MIN);
245     nqe::internal::CachedNetworkQuality read_network_quality;
246     network_quality_store.Add(network_id,
247                               cached_network_quality_strength_unknown);
248     EXPECT_TRUE(
249         network_quality_store.GetById(network_id, &read_network_quality));
250     EXPECT_EQ(cached_network_quality_strength_unknown.network_quality(),
251               read_network_quality.network_quality());
252   }
253 
254   {
255     // Entry will be added for (2G, "test1") with signal strength value of 3.
256     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
257                                         "test1", 3);
258     nqe::internal::CachedNetworkQuality read_network_quality;
259     network_quality_store.Add(network_id, cached_network_quality_strength_3);
260     EXPECT_TRUE(
261         network_quality_store.GetById(network_id, &read_network_quality));
262     EXPECT_EQ(cached_network_quality_strength_3.network_quality(),
263               read_network_quality.network_quality());
264   }
265 
266   {
267     // Now with cached entries for signal strengths INT32_MIN and 3, verify
268     // across the range of strength values that the closest value match will be
269     // returned when looking up (2G, "test1", signal_strength).
270     for (int32_t signal_strength = 0; signal_strength <= 4; ++signal_strength) {
271       nqe::internal::CachedNetworkQuality expected_cached_network_quality =
272           cached_network_quality_strength_3;
273       nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
274                                           "test1", signal_strength);
275       nqe::internal::CachedNetworkQuality read_network_quality;
276       EXPECT_TRUE(
277           network_quality_store.GetById(network_id, &read_network_quality));
278       EXPECT_EQ(expected_cached_network_quality.network_quality(),
279                 read_network_quality.network_quality());
280     }
281   }
282 
283   {
284     // When the current network does not have signal strength available, then
285     // the cached value that corresponds to unknown signal strength should be
286     // returned.
287     int32_t signal_strength = INT32_MIN;
288     nqe::internal::CachedNetworkQuality expected_cached_network_quality =
289         cached_network_quality_strength_unknown;
290     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
291                                         "test1", signal_strength);
292     nqe::internal::CachedNetworkQuality read_network_quality;
293     EXPECT_TRUE(
294         network_quality_store.GetById(network_id, &read_network_quality));
295     EXPECT_EQ(expected_cached_network_quality.network_quality(),
296               read_network_quality.network_quality());
297   }
298 }
299 
300 // Tests if the cache size remains bounded. Also, ensure that the cache is
301 // LRU.
TEST(NetworkQualityStoreTest,TestLRUCacheMaximumSize)302 TEST(NetworkQualityStoreTest, TestLRUCacheMaximumSize) {
303   nqe::internal::NetworkQualityStore network_quality_store;
304   base::SimpleTestTickClock tick_clock;
305 
306   // Add more networks than the maximum size of the cache.
307   const size_t network_count = 21;
308 
309   nqe::internal::CachedNetworkQuality read_network_quality(
310       tick_clock.NowTicks(),
311       nqe::internal::NetworkQuality(base::Seconds(0), base::Seconds(0), 0),
312       EFFECTIVE_CONNECTION_TYPE_2G);
313 
314   for (size_t i = 0; i < network_count; ++i) {
315     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
316                                         "test" + base::NumberToString(i), 0);
317 
318     const nqe::internal::CachedNetworkQuality network_quality(
319         tick_clock.NowTicks(),
320         nqe::internal::NetworkQuality(base::Seconds(1), base::Seconds(1), 1),
321         EFFECTIVE_CONNECTION_TYPE_2G);
322     network_quality_store.Add(network_id, network_quality);
323     tick_clock.Advance(base::Seconds(1));
324   }
325 
326   base::TimeTicks earliest_last_update_time = tick_clock.NowTicks();
327   size_t cache_match_count = 0;
328   for (size_t i = 0; i < network_count; ++i) {
329     nqe::internal::NetworkID network_id(NetworkChangeNotifier::CONNECTION_2G,
330                                         "test" + base::NumberToString(i), 0);
331 
332     nqe::internal::CachedNetworkQuality network_quality(
333         tick_clock.NowTicks(),
334         nqe::internal::NetworkQuality(base::Seconds(0), base::Seconds(0), 0),
335         EFFECTIVE_CONNECTION_TYPE_2G);
336     if (network_quality_store.GetById(network_id, &network_quality)) {
337       cache_match_count++;
338       earliest_last_update_time = std::min(earliest_last_update_time,
339                                            network_quality.last_update_time());
340     }
341   }
342 
343   // Ensure that the number of entries in cache are fewer than |network_count|.
344   EXPECT_LT(cache_match_count, network_count);
345   EXPECT_GT(cache_match_count, 0u);
346 
347   // Ensure that only LRU entries are cached by comparing the
348   // |earliest_last_update_time|.
349   EXPECT_EQ(tick_clock.NowTicks() - base::Seconds(cache_match_count),
350             earliest_last_update_time);
351 }
352 
353 }  // namespace
354 
355 }  // namespace net
356