wifi_data_provider_common_unittest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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
5#include <vector>
6
7#include "base/memory/scoped_ptr.h"
8#include "base/string_util.h"
9#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
10#include "base/utf_string_conversions.h"
11#include "content/browser/geolocation/wifi_data_provider_common.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15using testing::_;
16using testing::AtLeast;
17using testing::DoDefault;
18using testing::Invoke;
19using testing::Return;
20
21namespace content {
22
23class MockWlanApi : public WifiDataProviderCommon::WlanApiInterface {
24 public:
25  MockWlanApi() : calls_(0), bool_return_(true) {
26    ANNOTATE_BENIGN_RACE(&calls_, "This is a test-only data race on a counter");
27    ON_CALL(*this, GetAccessPointData(_))
28        .WillByDefault(Invoke(this, &MockWlanApi::GetAccessPointDataInternal));
29  }
30
31  MOCK_METHOD1(GetAccessPointData, bool(WifiData::AccessPointDataSet* data));
32
33  int calls_;
34  bool bool_return_;
35  WifiData::AccessPointDataSet data_out_;
36
37 private:
38  bool GetAccessPointDataInternal(WifiData::AccessPointDataSet* data) {
39    ++calls_;
40    *data = data_out_;
41    return bool_return_;
42  }
43};
44
45class MockPollingPolicy :public PollingPolicyInterface {
46 public:
47  MockPollingPolicy() {
48    ON_CALL(*this,PollingInterval())
49        .WillByDefault(Return(1));
50    ON_CALL(*this,NoWifiInterval())
51        .WillByDefault(Return(1));
52  }
53
54  MOCK_METHOD0(PollingInterval, int());
55  MOCK_METHOD0(NoWifiInterval, int());
56
57  virtual void UpdatePollingInterval(bool) {}
58};
59
60// Stops the specified (nested) message loop when the listener is called back.
61class MessageLoopQuitListener
62    : public WifiDataProviderCommon::ListenerInterface {
63 public:
64  explicit MessageLoopQuitListener(MessageLoop* message_loop)
65      : message_loop_to_quit_(message_loop) {
66    CHECK(message_loop_to_quit_ != NULL);
67  }
68  // ListenerInterface
69  virtual void DeviceDataUpdateAvailable(
70      DeviceDataProvider<WifiData>* provider) OVERRIDE {
71    // Provider should call back on client's thread.
72    EXPECT_EQ(MessageLoop::current(), message_loop_to_quit_);
73    provider_ = provider;
74    message_loop_to_quit_->QuitNow();
75  }
76  MessageLoop* message_loop_to_quit_;
77  DeviceDataProvider<WifiData>* provider_;
78};
79
80
81class WifiDataProviderCommonWithMock : public WifiDataProviderCommon {
82 public:
83  WifiDataProviderCommonWithMock()
84      : new_wlan_api_(new MockWlanApi),
85        new_polling_policy_(new MockPollingPolicy) {}
86
87  // WifiDataProviderCommon
88  virtual WlanApiInterface* NewWlanApi() OVERRIDE {
89    CHECK(new_wlan_api_ != NULL);
90    return new_wlan_api_.release();
91  }
92  virtual PollingPolicyInterface* NewPollingPolicy() OVERRIDE {
93    CHECK(new_polling_policy_ != NULL);
94    return new_polling_policy_.release();
95  }
96
97  scoped_ptr<MockWlanApi> new_wlan_api_;
98  scoped_ptr<MockPollingPolicy> new_polling_policy_;
99
100 private:
101  virtual ~WifiDataProviderCommonWithMock() {}
102
103  DISALLOW_COPY_AND_ASSIGN(WifiDataProviderCommonWithMock);
104};
105
106WifiDataProviderImplBase* CreateWifiDataProviderCommonWithMock() {
107  return new WifiDataProviderCommonWithMock;
108}
109
110// Main test fixture
111class GeolocationWifiDataProviderCommonTest : public testing::Test {
112 public:
113  GeolocationWifiDataProviderCommonTest()
114      : quit_listener_(&main_message_loop_) {
115  }
116
117  virtual void SetUp() {
118    provider_ = new WifiDataProviderCommonWithMock;
119    wlan_api_ = provider_->new_wlan_api_.get();
120    polling_policy_ = provider_->new_polling_policy_.get();
121    provider_->AddListener(&quit_listener_);
122  }
123  virtual void TearDown() {
124    provider_->RemoveListener(&quit_listener_);
125    provider_->StopDataProvider();
126    provider_ = NULL;
127  }
128
129 protected:
130  MessageLoop main_message_loop_;
131  MessageLoopQuitListener quit_listener_;
132  scoped_refptr<WifiDataProviderCommonWithMock> provider_;
133  MockWlanApi* wlan_api_;
134  MockPollingPolicy* polling_policy_;
135};
136
137TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) {
138  // Test fixture members were SetUp correctly.
139  EXPECT_EQ(&main_message_loop_, MessageLoop::current());
140  EXPECT_TRUE(NULL != provider_.get());
141  EXPECT_TRUE(NULL != wlan_api_);
142}
143
144TEST_F(GeolocationWifiDataProviderCommonTest, StartThread) {
145  EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
146      .Times(AtLeast(1));
147  EXPECT_CALL(*polling_policy_, PollingInterval())
148      .Times(AtLeast(1));
149  EXPECT_TRUE(provider_->StartDataProvider());
150  main_message_loop_.Run();
151  SUCCEED();
152}
153
154TEST_F(GeolocationWifiDataProviderCommonTest, NoWifi){
155  EXPECT_CALL(*polling_policy_, NoWifiInterval())
156      .Times(AtLeast(1));
157  EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
158      .WillRepeatedly(Return(false));
159  provider_->StartDataProvider();
160  main_message_loop_.Run();
161}
162
163TEST_F(GeolocationWifiDataProviderCommonTest, IntermittentWifi){
164  EXPECT_CALL(*polling_policy_, PollingInterval())
165      .Times(AtLeast(1));
166  EXPECT_CALL(*polling_policy_, NoWifiInterval())
167      .Times(1);
168  EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
169      .WillOnce(Return(true))
170      .WillOnce(Return(false))
171      .WillRepeatedly(DoDefault());
172
173  AccessPointData single_access_point;
174  single_access_point.channel = 2;
175  single_access_point.mac_address = 3;
176  single_access_point.radio_signal_strength = 4;
177  single_access_point.signal_to_noise = 5;
178  single_access_point.ssid = ASCIIToUTF16("foossid");
179  wlan_api_->data_out_.insert(single_access_point);
180
181  provider_->StartDataProvider();
182  main_message_loop_.Run();
183  main_message_loop_.Run();
184}
185
186TEST_F(GeolocationWifiDataProviderCommonTest, DoAnEmptyScan) {
187  EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
188      .Times(AtLeast(1));
189  EXPECT_CALL(*polling_policy_, PollingInterval())
190      .Times(AtLeast(1));
191  EXPECT_TRUE(provider_->StartDataProvider());
192  main_message_loop_.Run();
193  // Check we had at least one call. The worker thread may have raced ahead
194  // and made multiple calls.
195  EXPECT_GT(wlan_api_->calls_, 0);
196  WifiData data;
197  EXPECT_TRUE(provider_->GetData(&data));
198  EXPECT_EQ(0, static_cast<int>(data.access_point_data.size()));
199}
200
201TEST_F(GeolocationWifiDataProviderCommonTest, DoScanWithResults) {
202  EXPECT_CALL(*wlan_api_, GetAccessPointData(_))
203      .Times(AtLeast(1));
204  EXPECT_CALL(*polling_policy_, PollingInterval())
205      .Times(AtLeast(1));
206  AccessPointData single_access_point;
207  single_access_point.channel = 2;
208  single_access_point.mac_address = 3;
209  single_access_point.radio_signal_strength = 4;
210  single_access_point.signal_to_noise = 5;
211  single_access_point.ssid = ASCIIToUTF16("foossid");
212  wlan_api_->data_out_.insert(single_access_point);
213
214  EXPECT_TRUE(provider_->StartDataProvider());
215  main_message_loop_.Run();
216  EXPECT_GT(wlan_api_->calls_, 0);
217  WifiData data;
218  EXPECT_TRUE(provider_->GetData(&data));
219  EXPECT_EQ(1, static_cast<int>(data.access_point_data.size()));
220  EXPECT_EQ(single_access_point.ssid, data.access_point_data.begin()->ssid);
221}
222
223TEST_F(GeolocationWifiDataProviderCommonTest,
224       StartThreadViaDeviceDataProvider) {
225  MessageLoopQuitListener quit_listener(&main_message_loop_);
226  WifiDataProvider::SetFactory(CreateWifiDataProviderCommonWithMock);
227  DeviceDataProvider<WifiData>::Register(&quit_listener);
228  main_message_loop_.Run();
229  DeviceDataProvider<WifiData>::Unregister(&quit_listener);
230  DeviceDataProvider<WifiData>::ResetFactory();
231}
232
233}  // namespace content
234