xref: /aosp_15_r20/external/cronet/net/nqe/network_qualities_prefs_manager_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_qualities_prefs_manager.h"
6 
7 #include <algorithm>
8 #include <map>
9 #include <memory>
10 
11 #include "base/run_loop.h"
12 #include "base/sequence_checker.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "base/values.h"
16 #include "net/base/network_change_notifier.h"
17 #include "net/nqe/effective_connection_type.h"
18 #include "net/nqe/network_id.h"
19 #include "net/nqe/network_quality_estimator_test_util.h"
20 #include "net/nqe/network_quality_store.h"
21 #include "net/test/test_with_task_environment.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 
24 namespace net {
25 
26 namespace {
27 
28 class TestPrefDelegate : public NetworkQualitiesPrefsManager::PrefDelegate {
29  public:
30   TestPrefDelegate() = default;
31 
32   TestPrefDelegate(const TestPrefDelegate&) = delete;
33   TestPrefDelegate& operator=(const TestPrefDelegate&) = delete;
34 
~TestPrefDelegate()35   ~TestPrefDelegate() override {
36     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
37   }
38 
SetDictionaryValue(const base::Value::Dict & dict)39   void SetDictionaryValue(const base::Value::Dict& dict) override {
40     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
41 
42     write_count_++;
43     value_ = dict.Clone();
44     ASSERT_EQ(dict.size(), value_.size());
45   }
46 
GetDictionaryValue()47   base::Value::Dict GetDictionaryValue() override {
48     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
49 
50     read_count_++;
51     return value_.Clone();
52   }
53 
write_count() const54   size_t write_count() const {
55     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
56     return write_count_;
57   }
58 
read_count() const59   size_t read_count() const {
60     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
61     return read_count_;
62   }
63 
64  private:
65   // Number of times prefs were written and read, respectively..
66   size_t write_count_ = 0;
67   size_t read_count_ = 0;
68 
69   // Current value of the prefs.
70   base::Value::Dict value_;
71 
72   SEQUENCE_CHECKER(sequence_checker_);
73 };
74 
75 using NetworkQualitiesPrefManager = TestWithTaskEnvironment;
76 
TEST_F(NetworkQualitiesPrefManager,Write)77 TEST_F(NetworkQualitiesPrefManager, Write) {
78   // Force set the ECT to Slow 2G so that the ECT does not match the default
79   // ECT for the current connection type. This forces the prefs to be written
80   // for the current connection.
81   std::map<std::string, std::string> variation_params;
82   variation_params["force_effective_connection_type"] = "Slow-2G";
83   TestNetworkQualityEstimator estimator(variation_params);
84 
85   auto prefs_delegate = std::make_unique<TestPrefDelegate>();
86   TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
87 
88   NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
89   manager.InitializeOnNetworkThread(&estimator);
90   base::RunLoop().RunUntilIdle();
91 
92   // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
93   EXPECT_EQ(2u, prefs_delegate_ptr->read_count());
94 
95   estimator.SimulateNetworkChange(
96       NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
97   EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
98   // Network quality generated from the default observation must be written.
99   base::RunLoop().RunUntilIdle();
100   EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
101 
102   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
103   // Run a request so that effective connection type is recomputed, and
104   // observers are notified of change in the network quality.
105   estimator.RunOneRequest();
106   base::RunLoop().RunUntilIdle();
107   EXPECT_EQ(4u, prefs_delegate_ptr->write_count());
108 
109   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
110   // Run a request so that effective connection type is recomputed, and
111   // observers are notified of change in the network quality..
112   estimator.RunOneRequest();
113   base::RunLoop().RunUntilIdle();
114   EXPECT_EQ(5u, prefs_delegate_ptr->write_count());
115 
116   // Prefs should not be read again.
117   EXPECT_EQ(2u, prefs_delegate_ptr->read_count());
118 
119   manager.ShutdownOnPrefSequence();
120 }
121 
TEST_F(NetworkQualitiesPrefManager,WriteWhenMatchingExpectedECT)122 TEST_F(NetworkQualitiesPrefManager, WriteWhenMatchingExpectedECT) {
123   // Force set the ECT to Slow 2G so that the ECT does not match the default
124   // ECT for the current connection type. This forces the prefs to be written
125   // for the current connection.
126   std::map<std::string, std::string> variation_params;
127   variation_params["force_effective_connection_type"] = "Slow-2G";
128   TestNetworkQualityEstimator estimator(variation_params);
129 
130   auto prefs_delegate = std::make_unique<TestPrefDelegate>();
131   TestPrefDelegate* prefs_delegate_ptr = prefs_delegate.get();
132 
133   NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
134   manager.InitializeOnNetworkThread(&estimator);
135   base::RunLoop().RunUntilIdle();
136 
137   // Prefs must be read at when NetworkQualitiesPrefsManager is constructed.
138   EXPECT_EQ(2u, prefs_delegate_ptr->read_count());
139 
140   const nqe::internal::NetworkID network_id(
141       NetworkChangeNotifier::ConnectionType::CONNECTION_4G, "test", INT32_MIN);
142 
143   estimator.SimulateNetworkChange(network_id.type, network_id.id);
144   EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
145   // Network quality generated from the default observation must be written.
146   base::RunLoop().RunUntilIdle();
147   EXPECT_EQ(3u, prefs_delegate_ptr->write_count());
148 
149   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
150   // Run a request so that effective connection type is recomputed, and
151   // observers are notified of change in the network quality.
152   estimator.RunOneRequest();
153   base::RunLoop().RunUntilIdle();
154   EXPECT_EQ(4u, prefs_delegate_ptr->write_count());
155 
156   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_3G);
157   // Run a request so that effective connection type is recomputed, and
158   // observers are notified of change in the network quality..
159   estimator.RunOneRequest();
160   base::RunLoop().RunUntilIdle();
161   EXPECT_EQ(5u, prefs_delegate_ptr->write_count());
162 
163   // Prefs should not be read again.
164   EXPECT_EQ(2u, prefs_delegate_ptr->read_count());
165 
166   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
167   EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_3G,
168             manager.ForceReadPrefsForTesting()
169                 .find(network_id)
170                 ->second.effective_connection_type());
171 
172   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_4G);
173   estimator.RunOneRequest();
174   base::RunLoop().RunUntilIdle();
175 
176   // Network Quality should be persisted to disk even if it matches the typical
177   // quality of the network. See crbug.com/890859.
178   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
179   EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().count(network_id));
180   EXPECT_EQ(6u, prefs_delegate_ptr->write_count());
181 
182   manager.ShutdownOnPrefSequence();
183 }
184 
TEST_F(NetworkQualitiesPrefManager,WriteAndReadWithMultipleNetworkIDs)185 TEST_F(NetworkQualitiesPrefManager, WriteAndReadWithMultipleNetworkIDs) {
186   static const size_t kMaxCacheSize = 20u;
187 
188   // Force set the ECT to Slow 2G so that the ECT does not match the default
189   // ECT for the current connection type. This forces the prefs to be written
190   // for the current connection.
191   std::map<std::string, std::string> variation_params;
192   variation_params["force_effective_connection_type"] = "Slow-2G";
193   TestNetworkQualityEstimator estimator(variation_params);
194 
195   auto prefs_delegate = std::make_unique<TestPrefDelegate>();
196 
197   NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
198   manager.InitializeOnNetworkThread(&estimator);
199   base::RunLoop().RunUntilIdle();
200 
201   estimator.SimulateNetworkChange(
202       NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test");
203 
204   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
205 
206   estimator.set_recent_effective_connection_type(
207       EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
208   // Run a request so that effective connection type is recomputed, and
209   // observers are notified of change in the network quality.
210   estimator.RunOneRequest();
211   base::RunLoop().RunUntilIdle();
212   // Verify that the observer was notified, and the updated network quality was
213   // written to the prefs.
214   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
215 
216   // Change the network ID.
217   for (size_t i = 0; i < kMaxCacheSize; ++i) {
218     estimator.SimulateNetworkChange(
219         NetworkChangeNotifier::ConnectionType::CONNECTION_2G,
220         "test" + base::NumberToString(i));
221 
222     estimator.RunOneRequest();
223     base::RunLoop().RunUntilIdle();
224 
225     EXPECT_EQ(std::min(i + 3, kMaxCacheSize),
226               manager.ForceReadPrefsForTesting().size());
227   }
228 
229   std::map<nqe::internal::NetworkID, nqe::internal::CachedNetworkQuality>
230       read_prefs = manager.ForceReadPrefsForTesting();
231 
232   // Verify the contents of the prefs.
233   size_t count_2g_entries = 0;
234   for (std::map<nqe::internal::NetworkID,
235                 nqe::internal::CachedNetworkQuality>::const_iterator it =
236            read_prefs.begin();
237        it != read_prefs.end(); ++it) {
238     if (it->first.type ==
239         NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN) {
240       continue;
241     }
242     EXPECT_EQ(0u, it->first.id.find("test", 0u));
243     EXPECT_EQ(NetworkChangeNotifier::ConnectionType::CONNECTION_2G,
244               it->first.type);
245     EXPECT_EQ(EFFECTIVE_CONNECTION_TYPE_SLOW_2G,
246               it->second.effective_connection_type());
247     ++count_2g_entries;
248   }
249 
250   // At most one entry should be for the network with connection type
251   // NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN.
252   EXPECT_LE(kMaxCacheSize - 1, count_2g_entries);
253 
254   estimator.OnPrefsRead(read_prefs);
255 
256   manager.ShutdownOnPrefSequence();
257 }
258 
259 // Verifies that the prefs are cleared correctly.
TEST_F(NetworkQualitiesPrefManager,ClearPrefs)260 TEST_F(NetworkQualitiesPrefManager, ClearPrefs) {
261   // Force set the ECT to Slow 2G so that the ECT does not match the default
262   // ECT for the current connection type. This forces the prefs to be written
263   // for the current connection.
264   std::map<std::string, std::string> variation_params;
265   variation_params["force_effective_connection_type"] = "Slow-2G";
266   TestNetworkQualityEstimator estimator(variation_params);
267 
268   auto prefs_delegate = std::make_unique<TestPrefDelegate>();
269 
270   NetworkQualitiesPrefsManager manager(std::move(prefs_delegate));
271   manager.InitializeOnNetworkThread(&estimator);
272   base::RunLoop().RunUntilIdle();
273 
274   estimator.SimulateNetworkChange(
275       NetworkChangeNotifier::ConnectionType::CONNECTION_UNKNOWN, "test");
276 
277   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
278 
279   estimator.set_recent_effective_connection_type(
280       EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
281   // Run a request so that effective connection type is recomputed, and
282   // observers are notified of change in the network quality.
283   estimator.RunOneRequest();
284   base::RunLoop().RunUntilIdle();
285   // Verify that the observer was notified, and the updated network quality was
286   // written to the prefs.
287   EXPECT_EQ(2u, manager.ForceReadPrefsForTesting().size());
288 
289   // Prefs must be completely cleared.
290   manager.ClearPrefs();
291   EXPECT_EQ(0u, manager.ForceReadPrefsForTesting().size());
292   estimator.set_recent_effective_connection_type(EFFECTIVE_CONNECTION_TYPE_2G);
293   // Run a request so that effective connection type is recomputed, and
294   // observers are notified of change in the network quality.
295   estimator.RunOneRequest();
296   base::RunLoop().RunUntilIdle();
297   // Verify that the observer was notified, and the updated network quality was
298   // written to the prefs.
299   EXPECT_EQ(1u, manager.ForceReadPrefsForTesting().size());
300   manager.ShutdownOnPrefSequence();
301 }
302 
303 }  // namespace
304 
305 }  // namespace net
306