network_qualities_prefs_manager_unittest.cc 11 KB

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