position_cache_impl_unittest.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright 2018 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 "services/device/geolocation/position_cache_impl.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/strings/string_number_conversions.h"
  8. #include "base/strings/utf_string_conversions.h"
  9. #include "base/test/task_environment.h"
  10. #include "net/base/network_change_notifier.h"
  11. #include "services/device/geolocation/position_cache_test_util.h"
  12. #include "services/device/public/cpp/geolocation/geoposition.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. namespace device {
  15. class PositionCacheImplTest : public ::testing::Test {
  16. public:
  17. PositionCacheImplTest()
  18. : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
  19. network_change_notifier_(
  20. net::NetworkChangeNotifier::CreateMockIfNeeded()),
  21. cache_(task_environment_.GetMockTickClock()) {}
  22. protected:
  23. base::test::TaskEnvironment task_environment_;
  24. std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
  25. PositionCacheImpl cache_;
  26. };
  27. TEST_F(PositionCacheImplTest, EmptyCacheReturnsNoLocations) {
  28. WifiData empty_wifi_data;
  29. EXPECT_EQ(nullptr, cache_.FindPosition(empty_wifi_data));
  30. EXPECT_EQ(0U, cache_.GetPositionCacheSize());
  31. }
  32. TEST_F(PositionCacheImplTest, CanAddEmptyWifiData) {
  33. WifiData empty_wifi_data;
  34. mojom::Geoposition geoposition = testing::CreateGeoposition(1);
  35. cache_.CachePosition(empty_wifi_data, geoposition);
  36. const mojom::Geoposition* found_position =
  37. cache_.FindPosition(empty_wifi_data);
  38. ASSERT_NE(nullptr, found_position);
  39. EXPECT_TRUE(geoposition.Equals(*found_position));
  40. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  41. }
  42. TEST_F(PositionCacheImplTest, FirstAddedWifiDataReturned) {
  43. WifiData wifi_data = testing::CreateDefaultUniqueWifiData();
  44. mojom::Geoposition geoposition = testing::CreateGeoposition(1);
  45. cache_.CachePosition(wifi_data, geoposition);
  46. const mojom::Geoposition* found_position = cache_.FindPosition(wifi_data);
  47. ASSERT_NE(nullptr, found_position);
  48. EXPECT_TRUE(geoposition.Equals(*found_position));
  49. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  50. }
  51. TEST_F(PositionCacheImplTest, LastAddedWifiDataReturned) {
  52. cache_.CachePosition(testing::CreateDefaultUniqueWifiData(),
  53. testing::CreateGeoposition(1));
  54. cache_.CachePosition(testing::CreateDefaultUniqueWifiData(),
  55. testing::CreateGeoposition(2));
  56. WifiData final_wifi_data = testing::CreateDefaultUniqueWifiData();
  57. mojom::Geoposition final_geoposition = testing::CreateGeoposition(5);
  58. cache_.CachePosition(final_wifi_data, final_geoposition);
  59. const mojom::Geoposition* found_position =
  60. cache_.FindPosition(final_wifi_data);
  61. ASSERT_NE(nullptr, found_position);
  62. EXPECT_TRUE(final_geoposition.Equals(*found_position));
  63. EXPECT_EQ(3U, cache_.GetPositionCacheSize());
  64. }
  65. TEST_F(PositionCacheImplTest, MaxPositionsFound) {
  66. std::vector<std::pair<WifiData, mojom::Geoposition>> test_data;
  67. for (size_t i = 0; i < PositionCacheImpl::kMaximumSize; ++i) {
  68. test_data.push_back(std::make_pair(testing::CreateDefaultUniqueWifiData(),
  69. testing::CreateGeoposition(i)));
  70. }
  71. // Populate the cache
  72. for (const auto& test_data_pair : test_data) {
  73. cache_.CachePosition(test_data_pair.first, test_data_pair.second);
  74. }
  75. EXPECT_EQ(PositionCacheImpl::kMaximumSize, cache_.GetPositionCacheSize());
  76. // Make sure all elements are cached.
  77. for (const auto& test_data_pair : test_data) {
  78. const mojom::Geoposition* found_position =
  79. cache_.FindPosition(test_data_pair.first);
  80. ASSERT_NE(nullptr, found_position);
  81. EXPECT_TRUE(test_data_pair.second.Equals(*found_position));
  82. }
  83. }
  84. TEST_F(PositionCacheImplTest, Eviction) {
  85. WifiData initial_wifi_data = testing::CreateDefaultUniqueWifiData();
  86. mojom::Geoposition initial_geoposition = testing::CreateGeoposition(1);
  87. cache_.CachePosition(initial_wifi_data, initial_geoposition);
  88. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  89. // Add as many entries as the cache's size limit, which should evict
  90. // |initial_wifi_data|.
  91. for (size_t i = 0; i < PositionCacheImpl::kMaximumSize; ++i) {
  92. cache_.CachePosition(testing::CreateDefaultUniqueWifiData(),
  93. testing::CreateGeoposition(i));
  94. }
  95. EXPECT_EQ(PositionCacheImpl::kMaximumSize, cache_.GetPositionCacheSize());
  96. // |initial_wifi_data| can no longer be found in cache_.
  97. ASSERT_EQ(nullptr, cache_.FindPosition(initial_wifi_data));
  98. }
  99. TEST_F(PositionCacheImplTest, LastUsedPositionRemembered) {
  100. // Initially, invalid.
  101. EXPECT_FALSE(ValidateGeoposition(cache_.GetLastUsedNetworkPosition()));
  102. // Remembered after setting.
  103. mojom::Geoposition position = testing::CreateGeoposition(4);
  104. cache_.SetLastUsedNetworkPosition(position);
  105. EXPECT_TRUE(position.Equals(cache_.GetLastUsedNetworkPosition()));
  106. }
  107. TEST_F(PositionCacheImplTest, EntryEvictedAfterMaxLifetimeReached) {
  108. WifiData initial_wifi_data = testing::CreateDefaultUniqueWifiData();
  109. mojom::Geoposition initial_geoposition = testing::CreateGeoposition(1);
  110. cache_.CachePosition(initial_wifi_data, initial_geoposition);
  111. // Initially, the position is there.
  112. const mojom::Geoposition* found_position =
  113. cache_.FindPosition(initial_wifi_data);
  114. ASSERT_NE(nullptr, found_position);
  115. EXPECT_TRUE(initial_geoposition.Equals(*found_position));
  116. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  117. task_environment_.FastForwardBy(PositionCacheImpl::kMaximumLifetime);
  118. // Position was evicted.
  119. EXPECT_EQ(nullptr, cache_.FindPosition(initial_wifi_data));
  120. EXPECT_EQ(0U, cache_.GetPositionCacheSize());
  121. }
  122. TEST_F(PositionCacheImplTest, OnlyOldEntriesEvicted) {
  123. WifiData older_wifi_data = testing::CreateDefaultUniqueWifiData();
  124. mojom::Geoposition older_geoposition = testing::CreateGeoposition(1);
  125. cache_.CachePosition(older_wifi_data, older_geoposition);
  126. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  127. // Some time passes, but less than kMaximumLifetime
  128. task_environment_.FastForwardBy(PositionCacheImpl::kMaximumLifetime * 0.5);
  129. // Old position is still there.
  130. const mojom::Geoposition* found_position =
  131. cache_.FindPosition(older_wifi_data);
  132. ASSERT_NE(nullptr, found_position);
  133. EXPECT_TRUE(older_geoposition.Equals(*found_position));
  134. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  135. // New position is added.
  136. WifiData newer_wifi_data = testing::CreateDefaultUniqueWifiData();
  137. mojom::Geoposition newer_geoposition = testing::CreateGeoposition(2);
  138. cache_.CachePosition(newer_wifi_data, newer_geoposition);
  139. EXPECT_EQ(2U, cache_.GetPositionCacheSize());
  140. // Enough time passes to evict the older entry, but not enough to evict the
  141. // newer one.
  142. task_environment_.FastForwardBy(PositionCacheImpl::kMaximumLifetime * 0.75);
  143. EXPECT_EQ(nullptr, cache_.FindPosition(older_wifi_data));
  144. const mojom::Geoposition* found_newer_position =
  145. cache_.FindPosition(newer_wifi_data);
  146. ASSERT_NE(nullptr, found_newer_position);
  147. EXPECT_TRUE(newer_geoposition.Equals(*found_newer_position));
  148. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  149. }
  150. TEST_F(PositionCacheImplTest, NetworkChangeClearsEmptyWifiDataPosition) {
  151. // Cache a position for non-empty WifiData.
  152. WifiData initial_wifi_data = testing::CreateDefaultUniqueWifiData();
  153. mojom::Geoposition initial_geoposition = testing::CreateGeoposition(1);
  154. cache_.CachePosition(initial_wifi_data, initial_geoposition);
  155. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  156. // Cache a position for empty WifiData (wired network).
  157. WifiData empty_wifi_data;
  158. mojom::Geoposition empty_data_geoposition = testing::CreateGeoposition(2);
  159. cache_.CachePosition(empty_wifi_data, empty_data_geoposition);
  160. EXPECT_EQ(2U, cache_.GetPositionCacheSize());
  161. cache_.SetLastUsedNetworkPosition(initial_geoposition);
  162. // When network changes...
  163. net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
  164. net::NetworkChangeNotifier::CONNECTION_UNKNOWN);
  165. task_environment_.RunUntilIdle();
  166. // ... last network position is cleared
  167. EXPECT_FALSE(ValidateGeoposition(cache_.GetLastUsedNetworkPosition()));
  168. // And the position for empty WifiData is cleared, since we're probably on
  169. // a different wired network now.
  170. EXPECT_EQ(nullptr, cache_.FindPosition(empty_wifi_data));
  171. // But the position for non-empty WifiData remains, since our access point
  172. // scans remain valid even if we moved to a different access point.
  173. const mojom::Geoposition* found_position =
  174. cache_.FindPosition(initial_wifi_data);
  175. ASSERT_NE(nullptr, found_position);
  176. EXPECT_TRUE(initial_geoposition.Equals(*found_position));
  177. EXPECT_EQ(1U, cache_.GetPositionCacheSize());
  178. }
  179. } // namespace device