wifi_data_provider_common_unittest.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // Copyright (c) 2012 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/wifi_data_provider_common.h"
  5. #include <memory>
  6. #include "base/callback_helpers.h"
  7. #include "base/memory/raw_ptr.h"
  8. #include "base/run_loop.h"
  9. #include "base/strings/utf_string_conversions.h"
  10. #include "base/task/single_thread_task_runner.h"
  11. #include "base/test/task_environment.h"
  12. #include "base/threading/thread_task_runner_handle.h"
  13. #include "services/device/geolocation/wifi_data_provider_handle.h"
  14. #include "testing/gmock/include/gmock/gmock.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. using testing::_;
  17. using testing::AnyNumber;
  18. using testing::AtLeast;
  19. using testing::DoAll;
  20. using testing::Invoke;
  21. using testing::InvokeWithoutArgs;
  22. using testing::Return;
  23. using testing::SetArgPointee;
  24. using testing::WithArgs;
  25. namespace device {
  26. class MockWlanApi : public WifiDataProviderCommon::WlanApiInterface {
  27. public:
  28. MockWlanApi() {
  29. ON_CALL(*this, GetAccessPointData(_))
  30. .WillByDefault(DoAll(SetArgPointee<0>(data_out_), Return(true)));
  31. }
  32. MOCK_METHOD1(GetAccessPointData, bool(WifiData::AccessPointDataSet* data));
  33. private:
  34. WifiData::AccessPointDataSet data_out_;
  35. };
  36. class MockPollingPolicy : public WifiPollingPolicy {
  37. public:
  38. MockPollingPolicy() {
  39. ON_CALL(*this, InitialInterval()).WillByDefault(Return(0));
  40. ON_CALL(*this, PollingInterval()).WillByDefault(Return(1));
  41. ON_CALL(*this, NoWifiInterval()).WillByDefault(Return(1));
  42. // We are not interested in calls to UpdatePollingInterval() method.
  43. EXPECT_CALL(*this, UpdatePollingInterval(_)).Times(AnyNumber());
  44. }
  45. // WifiPollingPolicy implementation.
  46. MOCK_METHOD1(UpdatePollingInterval, void(bool));
  47. MOCK_METHOD0(InitialInterval, int());
  48. MOCK_METHOD0(PollingInterval, int());
  49. MOCK_METHOD0(NoWifiInterval, int());
  50. };
  51. class WifiDataProviderCommonWithMock : public WifiDataProviderCommon {
  52. public:
  53. WifiDataProviderCommonWithMock() : wlan_api_(new MockWlanApi) {}
  54. WifiDataProviderCommonWithMock(const WifiDataProviderCommonWithMock&) =
  55. delete;
  56. WifiDataProviderCommonWithMock& operator=(
  57. const WifiDataProviderCommonWithMock&) = delete;
  58. // WifiDataProviderCommon
  59. std::unique_ptr<WlanApiInterface> CreateWlanApi() override {
  60. return std::move(wlan_api_);
  61. }
  62. std::unique_ptr<WifiPollingPolicy> CreatePollingPolicy() override {
  63. auto policy = std::make_unique<MockPollingPolicy>();
  64. // Save a pointer to the MockPollingPolicy.
  65. polling_policy_ = policy.get();
  66. return std::move(policy);
  67. }
  68. std::unique_ptr<MockWlanApi> wlan_api_;
  69. raw_ptr<MockPollingPolicy> polling_policy_ = nullptr;
  70. private:
  71. ~WifiDataProviderCommonWithMock() override = default;
  72. };
  73. // Main test fixture
  74. class GeolocationWifiDataProviderCommonTest : public testing::Test {
  75. public:
  76. GeolocationWifiDataProviderCommonTest()
  77. : task_environment_(
  78. base::test::SingleThreadTaskEnvironment::MainThreadType::UI),
  79. wifi_data_callback_(base::DoNothing()) {}
  80. void TearDownProvider() {
  81. provider_->RemoveCallback(&wifi_data_callback_);
  82. provider_->StopDataProvider();
  83. provider_ = nullptr;
  84. wlan_api_ = nullptr;
  85. }
  86. // Some usage patterns cause the provider to be created and destroyed
  87. // frequently. Allow tests to simulate this behavior by recreating the
  88. // provider without resetting WifiPollingPolicy.
  89. void RecreateProvider() {
  90. if (provider_)
  91. TearDownProvider();
  92. provider_ = new WifiDataProviderCommonWithMock;
  93. provider_->AddCallback(&wifi_data_callback_);
  94. wlan_api_ = provider_->wlan_api_.get();
  95. // Initialize WifiPollingPolicy early so we can watch for calls to mocked
  96. // functions. Normally the policy is initialized in StartDataProvider.
  97. //
  98. // The policy should be initialized only once to ensure its state is
  99. // retained across restarts of the provider.
  100. if (!polling_policy_) {
  101. WifiPollingPolicy::Initialize(provider_->CreatePollingPolicy());
  102. polling_policy_ = provider_->polling_policy_;
  103. }
  104. }
  105. void SetUp() override { RecreateProvider(); }
  106. void TearDown() override {
  107. TearDownProvider();
  108. WifiPollingPolicy::Shutdown();
  109. polling_policy_ = nullptr;
  110. }
  111. protected:
  112. const base::test::SingleThreadTaskEnvironment task_environment_;
  113. WifiDataProviderHandle::WifiDataUpdateCallback wifi_data_callback_;
  114. scoped_refptr<WifiDataProviderCommonWithMock> provider_;
  115. raw_ptr<MockWlanApi> wlan_api_ = nullptr;
  116. raw_ptr<MockPollingPolicy> polling_policy_ = nullptr;
  117. };
  118. TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) {
  119. // Test fixture members were SetUp correctly.
  120. EXPECT_TRUE(provider_);
  121. EXPECT_TRUE(wlan_api_);
  122. EXPECT_TRUE(polling_policy_);
  123. }
  124. TEST_F(GeolocationWifiDataProviderCommonTest, NoWifi) {
  125. base::RunLoop run_loop;
  126. EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1);
  127. EXPECT_CALL(*polling_policy_, NoWifiInterval()).Times(AtLeast(1));
  128. EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
  129. .WillOnce(InvokeWithoutArgs([&run_loop]() {
  130. run_loop.Quit();
  131. return false;
  132. }));
  133. provider_->StartDataProvider();
  134. run_loop.Run();
  135. }
  136. TEST_F(GeolocationWifiDataProviderCommonTest, IntermittentWifi) {
  137. base::RunLoop run_loop;
  138. EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1);
  139. EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1));
  140. EXPECT_CALL(*polling_policy_, NoWifiInterval()).Times(1);
  141. EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
  142. .WillOnce(Return(true))
  143. .WillOnce(InvokeWithoutArgs([&run_loop]() {
  144. run_loop.Quit();
  145. return false;
  146. }));
  147. provider_->StartDataProvider();
  148. run_loop.Run();
  149. }
  150. // This test runs StartDataProvider() and expects that GetAccessPointData() is
  151. // called. The retrieved WifiData is expected to be empty.
  152. TEST_F(GeolocationWifiDataProviderCommonTest, DoAnEmptyScan) {
  153. base::RunLoop run_loop;
  154. EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1);
  155. EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1));
  156. EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
  157. .WillOnce(InvokeWithoutArgs([&run_loop]() {
  158. run_loop.Quit();
  159. return true;
  160. }));
  161. provider_->StartDataProvider();
  162. run_loop.Run();
  163. WifiData data;
  164. EXPECT_TRUE(provider_->GetData(&data));
  165. EXPECT_TRUE(data.access_point_data.empty());
  166. }
  167. // This test runs StartDataProvider() and expects that GetAccessPointData() is
  168. // called. Some mock WifiData is returned then and expected to be retrieved.
  169. TEST_F(GeolocationWifiDataProviderCommonTest, DoScanWithResults) {
  170. base::RunLoop run_loop;
  171. EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1);
  172. EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1));
  173. AccessPointData single_access_point;
  174. single_access_point.channel = 2;
  175. single_access_point.mac_address = u"00:11:22:33:44:55";
  176. single_access_point.radio_signal_strength = 4;
  177. single_access_point.signal_to_noise = 5;
  178. single_access_point.ssid = u"foossid";
  179. WifiData::AccessPointDataSet data_out({single_access_point});
  180. EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
  181. .WillOnce(WithArgs<0>(
  182. Invoke([&data_out, &run_loop](WifiData::AccessPointDataSet* data) {
  183. *data = data_out;
  184. run_loop.Quit();
  185. return true;
  186. })));
  187. provider_->StartDataProvider();
  188. run_loop.Run();
  189. WifiData data;
  190. EXPECT_TRUE(provider_->GetData(&data));
  191. ASSERT_EQ(1u, data.access_point_data.size());
  192. EXPECT_EQ(single_access_point.ssid, data.access_point_data.begin()->ssid);
  193. }
  194. TEST_F(GeolocationWifiDataProviderCommonTest, DelayedByPolicy) {
  195. static const int kPollingIntervalMillis = 1000;
  196. base::RunLoop run_loop;
  197. EXPECT_CALL(*polling_policy_, InitialInterval())
  198. // Initial scan: no delay
  199. .WillOnce(Return(0))
  200. // Third scan (after recreating the provider): scheduled after a delay
  201. .WillOnce(Return(kPollingIntervalMillis));
  202. EXPECT_CALL(*polling_policy_, PollingInterval())
  203. // Second scan: scheduled after a delay
  204. .WillOnce(Return(kPollingIntervalMillis));
  205. // Simulate a successful scan that found no wifi APs.
  206. EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
  207. .WillOnce(InvokeWithoutArgs([&run_loop]() {
  208. run_loop.Quit();
  209. return true;
  210. }));
  211. // The initial scan is scheduled with InitialInterval and should not be
  212. // delayed.
  213. provider_->StartDataProvider();
  214. EXPECT_FALSE(provider_->DelayedByPolicy());
  215. // Allow the pending call to DoWifiScanTask to proceed. This will fetch our
  216. // mock wifi AP data and mark the first scan complete. It will also schedule
  217. // a new scan to occur after PollingInterval.
  218. run_loop.Run();
  219. EXPECT_TRUE(provider_->DelayedByPolicy());
  220. // Destroy the provider and recreate it, which will schedule a new scan.
  221. // InitialInterval is used to schedule the new scan, but unlike the first
  222. // scan which was scheduled immediately, it will now incur a delay.
  223. RecreateProvider();
  224. provider_->StartDataProvider();
  225. EXPECT_TRUE(provider_->DelayedByPolicy());
  226. }
  227. } // namespace device