1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/wimax/wimax.h"
18
19 #include <memory>
20 #include <string>
21
22 #include "shill/dhcp/mock_dhcp_config.h"
23 #include "shill/dhcp/mock_dhcp_provider.h"
24 #include "shill/mock_manager.h"
25 #include "shill/mock_metrics.h"
26 #include "shill/nice_mock_control.h"
27 #include "shill/test_event_dispatcher.h"
28 #include "shill/testing.h"
29 #include "shill/wimax/mock_wimax_device_proxy.h"
30 #include "shill/wimax/mock_wimax_provider.h"
31 #include "shill/wimax/mock_wimax_service.h"
32
33 using base::Bind;
34 using base::Unretained;
35 using std::string;
36 using testing::_;
37 using testing::NiceMock;
38 using testing::Return;
39
40 namespace shill {
41
42 namespace {
43
44 const char kTestLinkName[] = "wm0";
45 const char kTestAddress[] = "01:23:45:67:89:ab";
46 const int kTestInterfaceIndex = 5;
47 const char kTestPath[] = "/org/chromium/WiMaxManager/Device/6";
48
49 } // namespace
50
51 class WiMaxTest : public testing::Test {
52 public:
WiMaxTest()53 WiMaxTest()
54 : proxy_(new MockWiMaxDeviceProxy()),
55 metrics_(&dispatcher_),
56 manager_(&control_, &dispatcher_, &metrics_),
57 dhcp_config_(new MockDHCPConfig(&control_,
58 kTestLinkName)),
59 device_(new WiMax(&control_, &dispatcher_, &metrics_, &manager_,
60 kTestLinkName, kTestAddress, kTestInterfaceIndex,
61 kTestPath)) {}
62
~WiMaxTest()63 virtual ~WiMaxTest() {}
64
65 protected:
66 class Target {
67 public:
~Target()68 virtual ~Target() {}
69
70 MOCK_METHOD1(EnabledStateChanged, void(const Error& error));
71 };
72
SetUp()73 virtual void SetUp() {
74 device_->set_dhcp_provider(&dhcp_provider_);
75 }
76
TearDown()77 virtual void TearDown() {
78 device_->SelectService(nullptr);
79 device_->pending_service_ = nullptr;
80 }
81
82 std::unique_ptr<MockWiMaxDeviceProxy> proxy_;
83 NiceMockControl control_;
84 EventDispatcherForTest dispatcher_;
85 NiceMock<MockMetrics> metrics_;
86 MockManager manager_;
87 MockDHCPProvider dhcp_provider_;
88 scoped_refptr<MockDHCPConfig> dhcp_config_;
89 WiMaxRefPtr device_;
90 };
91
TEST_F(WiMaxTest,Constructor)92 TEST_F(WiMaxTest, Constructor) {
93 EXPECT_EQ(kTestPath, device_->path());
94 EXPECT_FALSE(device_->scanning());
95 }
96
TEST_F(WiMaxTest,StartStop)97 TEST_F(WiMaxTest, StartStop) {
98 EXPECT_FALSE(device_->proxy_.get());
99 EXPECT_CALL(control_, CreateWiMaxDeviceProxy(_))
100 .WillOnce(ReturnAndReleasePointee(&proxy_));
101 EXPECT_CALL(*proxy_, Enable(_, _, _));
102 EXPECT_CALL(*proxy_, set_networks_changed_callback(_));
103 EXPECT_CALL(*proxy_, set_status_changed_callback(_));
104 EXPECT_CALL(*proxy_, Disable(_, _, _));
105 device_->Start(nullptr, EnabledStateChangedCallback());
106 ASSERT_TRUE(device_->proxy_.get());
107
108 scoped_refptr<MockWiMaxService> service(
109 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
110 device_->pending_service_ = service;
111 EXPECT_CALL(*service, SetState(Service::kStateIdle));
112 device_->networks_.insert("path");
113 MockWiMaxProvider provider;
114 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
115 EXPECT_CALL(provider, OnNetworksChanged());
116 device_->StartConnectTimeout();
117 device_->Stop(nullptr, EnabledStateChangedCallback());
118 EXPECT_TRUE(device_->networks_.empty());
119 EXPECT_FALSE(device_->IsConnectTimeoutStarted());
120 EXPECT_FALSE(device_->pending_service_);
121 }
122
TEST_F(WiMaxTest,OnServiceStopped)123 TEST_F(WiMaxTest, OnServiceStopped) {
124 scoped_refptr<NiceMock<MockWiMaxService>> service0(
125 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_));
126 scoped_refptr<MockWiMaxService> service1(
127 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
128 device_->SelectService(service0);
129 device_->pending_service_ = service1;
130
131 device_->OnServiceStopped(nullptr);
132 EXPECT_TRUE(device_->selected_service());
133 EXPECT_TRUE(device_->pending_service_);
134
135 device_->OnServiceStopped(service0);
136 EXPECT_FALSE(device_->selected_service());
137 EXPECT_TRUE(device_->pending_service_);
138
139 device_->OnServiceStopped(service1);
140 EXPECT_FALSE(device_->selected_service());
141 EXPECT_FALSE(device_->pending_service_);
142 }
143
TEST_F(WiMaxTest,OnNetworksChanged)144 TEST_F(WiMaxTest, OnNetworksChanged) {
145 MockWiMaxProvider provider;
146 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
147 EXPECT_CALL(provider, OnNetworksChanged());
148 device_->networks_.insert("foo");
149 RpcIdentifiers networks;
150 networks.push_back("bar");
151 networks.push_back("zoo");
152 networks.push_back("bar");
153 device_->OnNetworksChanged(networks);
154 EXPECT_EQ(2, device_->networks_.size());
155 EXPECT_TRUE(ContainsKey(device_->networks_, "bar"));
156 EXPECT_TRUE(ContainsKey(device_->networks_, "zoo"));
157 }
158
TEST_F(WiMaxTest,OnConnectComplete)159 TEST_F(WiMaxTest, OnConnectComplete) {
160 scoped_refptr<MockWiMaxService> service(
161 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
162 device_->pending_service_ = service;
163 EXPECT_CALL(*service, SetState(_)).Times(0);
164 EXPECT_TRUE(device_->pending_service_);
165 EXPECT_CALL(*service, SetState(Service::kStateFailure));
166 device_->OnConnectComplete(Error(Error::kOperationFailed));
167 EXPECT_FALSE(device_->pending_service_);
168 }
169
TEST_F(WiMaxTest,OnStatusChanged)170 TEST_F(WiMaxTest, OnStatusChanged) {
171 scoped_refptr<MockWiMaxService> service(
172 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
173
174 EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_);
175 device_->pending_service_ = service;
176 EXPECT_CALL(*service, SetState(_)).Times(0);
177 EXPECT_CALL(*service, ClearPassphrase()).Times(0);
178 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning);
179 EXPECT_TRUE(device_->pending_service_);
180 EXPECT_EQ(wimax_manager::kDeviceStatusScanning, device_->status_);
181
182 device_->status_ = wimax_manager::kDeviceStatusConnecting;
183 EXPECT_CALL(*service, SetState(Service::kStateFailure));
184 EXPECT_CALL(*service, ClearPassphrase()).Times(0);
185 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning);
186 EXPECT_FALSE(device_->pending_service_);
187
188 device_->status_ = wimax_manager::kDeviceStatusConnecting;
189 device_->SelectService(service);
190 EXPECT_CALL(*service, SetState(Service::kStateFailure));
191 EXPECT_CALL(*service, SetState(Service::kStateIdle));
192 EXPECT_CALL(*service, ClearPassphrase()).Times(0);
193 device_->OnStatusChanged(wimax_manager::kDeviceStatusScanning);
194 EXPECT_FALSE(device_->selected_service());
195
196 device_->pending_service_ = service;
197 device_->SelectService(service);
198 EXPECT_CALL(*service, SetState(_)).Times(0);
199 EXPECT_CALL(*service, ClearPassphrase()).Times(0);
200 device_->OnStatusChanged(wimax_manager::kDeviceStatusConnecting);
201 EXPECT_TRUE(device_->pending_service_);
202 EXPECT_TRUE(device_->selected_service());
203 EXPECT_EQ(wimax_manager::kDeviceStatusConnecting, device_->status_);
204
205 EXPECT_CALL(*service, SetState(Service::kStateIdle));
206 device_->SelectService(nullptr);
207 }
208
TEST_F(WiMaxTest,UseNoArpGateway)209 TEST_F(WiMaxTest, UseNoArpGateway) {
210 EXPECT_CALL(dhcp_provider_, CreateIPv4Config(kTestLinkName, _, false, _))
211 .WillOnce(Return(dhcp_config_));
212 device_->AcquireIPConfig();
213 }
214
TEST_F(WiMaxTest,DropService)215 TEST_F(WiMaxTest, DropService) {
216 scoped_refptr<NiceMock<MockWiMaxService>> service0(
217 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_));
218 scoped_refptr<MockWiMaxService> service1(
219 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
220 device_->SelectService(service0);
221 device_->pending_service_ = service1;
222 device_->StartConnectTimeout();
223
224 EXPECT_CALL(*service0, SetState(Service::kStateIdle)).Times(2);
225 EXPECT_CALL(*service1, SetState(Service::kStateIdle));
226 device_->DropService(Service::kStateIdle);
227 EXPECT_FALSE(device_->selected_service());
228 EXPECT_FALSE(device_->pending_service_);
229 EXPECT_FALSE(device_->IsConnectTimeoutStarted());
230
231 // Expect no crash.
232 device_->DropService(Service::kStateFailure);
233 }
234
TEST_F(WiMaxTest,OnDeviceVanished)235 TEST_F(WiMaxTest, OnDeviceVanished) {
236 device_->proxy_.reset(proxy_.release());
237 scoped_refptr<MockWiMaxService> service(
238 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
239 device_->pending_service_ = service;
240 EXPECT_CALL(*service, SetState(Service::kStateIdle));
241 device_->OnDeviceVanished();
242 EXPECT_FALSE(device_->proxy_.get());
243 EXPECT_FALSE(device_->pending_service_);
244 }
245
TEST_F(WiMaxTest,OnEnableComplete)246 TEST_F(WiMaxTest, OnEnableComplete) {
247 MockWiMaxProvider provider;
248 EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
249 RpcIdentifiers networks(1, "path");
250 EXPECT_CALL(*proxy_, Networks(_)).WillOnce(Return(networks));
251 device_->proxy_.reset(proxy_.release());
252 EXPECT_CALL(provider, OnNetworksChanged());
253 Target target;
254 EXPECT_CALL(target, EnabledStateChanged(_));
255 EnabledStateChangedCallback callback(
256 Bind(&Target::EnabledStateChanged, Unretained(&target)));
257 Error error;
258 device_->OnEnableComplete(callback, error);
259 EXPECT_EQ(1, device_->networks_.size());
260 EXPECT_TRUE(ContainsKey(device_->networks_, "path"));
261
262 EXPECT_TRUE(device_->proxy_.get());
263 error.Populate(Error::kOperationFailed);
264 EXPECT_CALL(target, EnabledStateChanged(_));
265 device_->OnEnableComplete(callback, error);
266 EXPECT_FALSE(device_->proxy_.get());
267 }
268
TEST_F(WiMaxTest,ConnectTimeout)269 TEST_F(WiMaxTest, ConnectTimeout) {
270 EXPECT_EQ(&dispatcher_, device_->dispatcher());
271 EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled());
272 EXPECT_FALSE(device_->IsConnectTimeoutStarted());
273 EXPECT_EQ(WiMax::kDefaultConnectTimeoutSeconds,
274 device_->connect_timeout_seconds_);
275 device_->connect_timeout_seconds_ = 0;
276 device_->StartConnectTimeout();
277 EXPECT_FALSE(device_->connect_timeout_callback_.IsCancelled());
278 EXPECT_TRUE(device_->IsConnectTimeoutStarted());
279 device_->dispatcher_ = nullptr;
280 device_->StartConnectTimeout(); // Expect no crash.
281 scoped_refptr<MockWiMaxService> service(
282 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
283 device_->pending_service_ = service;
284 EXPECT_CALL(*service, SetState(Service::kStateFailure));
285 dispatcher_.DispatchPendingEvents();
286 EXPECT_TRUE(device_->connect_timeout_callback_.IsCancelled());
287 EXPECT_FALSE(device_->IsConnectTimeoutStarted());
288 EXPECT_FALSE(device_->pending_service_);
289 }
290
TEST_F(WiMaxTest,ConnectTo)291 TEST_F(WiMaxTest, ConnectTo) {
292 static const char kPath[] = "/network/path";
293 scoped_refptr<MockWiMaxService> service(
294 new MockWiMaxService(&control_, nullptr, &metrics_, &manager_));
295 EXPECT_CALL(*service, SetState(Service::kStateAssociating));
296 device_->status_ = wimax_manager::kDeviceStatusScanning;
297 EXPECT_CALL(*service, GetNetworkObjectPath()).WillOnce(Return(kPath));
298 EXPECT_CALL(*proxy_, Connect(kPath, _, _, _, _))
299 .WillOnce(SetErrorTypeInArgument<2>(Error::kSuccess));
300 device_->proxy_.reset(proxy_.release());
301 Error error;
302 device_->ConnectTo(service, &error);
303 EXPECT_TRUE(error.IsSuccess());
304 EXPECT_EQ(service.get(), device_->pending_service_.get());
305 EXPECT_EQ(wimax_manager::kDeviceStatusUninitialized, device_->status_);
306 EXPECT_TRUE(device_->IsConnectTimeoutStarted());
307
308 device_->ConnectTo(service, &error);
309 EXPECT_EQ(Error::kInProgress, error.type());
310
311 device_->pending_service_ = nullptr;
312 }
313
TEST_F(WiMaxTest,IsIdle)314 TEST_F(WiMaxTest, IsIdle) {
315 EXPECT_TRUE(device_->IsIdle());
316 scoped_refptr<NiceMock<MockWiMaxService>> service(
317 new NiceMock<MockWiMaxService>(&control_, nullptr, &metrics_, &manager_));
318 device_->pending_service_ = service;
319 EXPECT_FALSE(device_->IsIdle());
320 device_->pending_service_ = nullptr;
321 device_->SelectService(service);
322 EXPECT_FALSE(device_->IsIdle());
323 }
324
325 } // namespace shill
326