blob: a6961726ce17aafded04bd1ac00f7f52b1164005 [file] [log] [blame]
Jason Glasgowef965562012-04-10 16:12:35 -04001// Copyright (c) 2012 The Chromium OS 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 "shill/cellular_capability_universal.h"
6
Nathan Williams4b7c2a82012-04-13 15:19:47 -04007#include <string>
8#include <vector>
9
Jason Glasgowef965562012-04-10 16:12:35 -040010#include <base/bind.h>
11#include <chromeos/dbus/service_constants.h>
12#include <gtest/gtest.h>
13#include <mobile_provider.h>
Ben Chanf6120e92012-06-28 18:56:17 -070014#include <ModemManager/ModemManager-names.h>
Jason Glasgowef965562012-04-10 16:12:35 -040015
16#include "shill/cellular.h"
17#include "shill/cellular_service.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040018#include "shill/dbus_adaptor.h"
Jason Glasgowef965562012-04-10 16:12:35 -040019#include "shill/error.h"
20#include "shill/event_dispatcher.h"
21#include "shill/mock_adaptors.h"
Jason Glasgow14521872012-05-07 19:12:15 -040022#include "shill/mock_cellular_service.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040023#include "shill/mock_dbus_properties_proxy.h"
Jason Glasgowef965562012-04-10 16:12:35 -040024#include "shill/mock_glib.h"
25#include "shill/mock_manager.h"
26#include "shill/mock_metrics.h"
27#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
28#include "shill/mock_mm1_modem_modemcdma_proxy.h"
29#include "shill/mock_mm1_modem_proxy.h"
30#include "shill/mock_mm1_modem_simple_proxy.h"
31#include "shill/mock_mm1_sim_proxy.h"
32#include "shill/mock_profile.h"
33#include "shill/mock_rtnl_handler.h"
34#include "shill/nice_mock_control.h"
35#include "shill/proxy_factory.h"
36
37using base::Bind;
38using base::Unretained;
39using std::string;
Nathan Williams4b7c2a82012-04-13 15:19:47 -040040using std::vector;
Jason Glasgowef965562012-04-10 16:12:35 -040041using testing::InSequence;
42using testing::NiceMock;
43using testing::Return;
Jason Glasgowcd0349c2012-05-03 23:32:15 -040044using testing::SaveArg;
Jason Glasgowef965562012-04-10 16:12:35 -040045using testing::_;
46
47namespace shill {
48
49MATCHER(IsSuccess, "") {
50 return arg.IsSuccess();
51}
52MATCHER(IsFailure, "") {
53 return arg.IsFailure();
54}
Jason Glasgow14521872012-05-07 19:12:15 -040055MATCHER_P(HasApn, expected_apn, "") {
56 string apn;
57 return (DBusProperties::GetString(arg,
58 CellularCapabilityUniversal::kConnectApn,
59 &apn) &&
60 apn == expected_apn);
61}
Jason Glasgowef965562012-04-10 16:12:35 -040062
63class CellularCapabilityUniversalTest : public testing::Test {
64 public:
65 CellularCapabilityUniversalTest()
66 : manager_(&control_, &dispatcher_, &metrics_, &glib_),
Ben Chan3ecdf822012-08-06 12:29:23 -070067 modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
68 modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
69 modem_proxy_(new mm1::MockModemProxy()),
70 modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
71 sim_proxy_(new mm1::MockSimProxy()),
72 properties_proxy_(new MockDBusPropertiesProxy()),
73 proxy_factory_(this),
74 capability_(NULL),
75 device_adaptor_(NULL),
76 provider_db_(NULL),
Jason Glasgowef965562012-04-10 16:12:35 -040077 cellular_(new Cellular(&control_,
78 &dispatcher_,
79 NULL,
80 &manager_,
81 "",
82 "",
83 0,
84 Cellular::kTypeUniversal,
85 "",
86 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040087 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070088 NULL,
89 &proxy_factory_)),
Jason Glasgow14521872012-05-07 19:12:15 -040090 service_(new MockCellularService(&control_,
91 &dispatcher_,
92 &metrics_,
93 &manager_,
Ben Chan3ecdf822012-08-06 12:29:23 -070094 cellular_)) {}
Jason Glasgowef965562012-04-10 16:12:35 -040095
96 virtual ~CellularCapabilityUniversalTest() {
97 cellular_->service_ = NULL;
98 capability_ = NULL;
99 device_adaptor_ = NULL;
100 }
101
102 virtual void SetUp() {
103 capability_ = dynamic_cast<CellularCapabilityUniversal *>(
104 cellular_->capability_.get());
Jason Glasgowef965562012-04-10 16:12:35 -0400105 device_adaptor_ =
106 dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
Jason Glasgow14521872012-05-07 19:12:15 -0400107 cellular_->service_ = service_;
Jason Glasgowef965562012-04-10 16:12:35 -0400108 }
109
110 virtual void TearDown() {
111 capability_->proxy_factory_ = NULL;
112 }
113
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400114 void InitProviderDB() {
115 const char kTestMobileProviderDBPath[] = "provider_db_unittest.bfd";
116
117 provider_db_ = mobile_provider_open_db(kTestMobileProviderDBPath);
118 ASSERT_TRUE(provider_db_);
119 cellular_->provider_db_ = provider_db_;
120 }
121
Jason Glasgowef965562012-04-10 16:12:35 -0400122 void InvokeEnable(bool enable, Error *error,
123 const ResultCallback &callback, int timeout) {
124 callback.Run(Error());
125 }
126 void InvokeEnableFail(bool enable, Error *error,
127 const ResultCallback &callback, int timeout) {
128 callback.Run(Error(Error::kOperationFailed));
129 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400130 void InvokeRegister(const string &operator_id, Error *error,
131 const ResultCallback &callback, int timeout) {
132 callback.Run(Error());
133 }
134
Gary Morainceba6aa2012-05-03 10:28:26 -0700135 void InvokeScan(Error *error, const DBusPropertyMapsCallback &callback,
136 int timeout) {
137 callback.Run(CellularCapabilityUniversal::ScanResults(), Error());
138 }
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400139 void ScanError(Error *error, const DBusPropertyMapsCallback &callback,
140 int timeout) {
141 error->Populate(Error::kOperationFailed);
142 }
Gary Morainceba6aa2012-05-03 10:28:26 -0700143
144 void Set3gppProxy() {
145 capability_->modem_3gpp_proxy_.reset(modem_3gpp_proxy_.release());
146 }
147
Jason Glasgow14521872012-05-07 19:12:15 -0400148 void SetSimpleProxy() {
149 capability_->modem_simple_proxy_.reset(modem_simple_proxy_.release());
150 }
151
Thieu Le3d275392012-07-20 15:32:58 -0700152 void ReleaseCapabilityProxies() {
153 capability_->ReleaseProxies();
154 }
155
Jason Glasgowef965562012-04-10 16:12:35 -0400156 MOCK_METHOD1(TestCallback, void(const Error &error));
157
158 protected:
159 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400160 static const char kSimPath[];
161 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400162
163 class TestProxyFactory : public ProxyFactory {
164 public:
165 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
166 test_(test) {}
167
168 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
169 const std::string &/* path */,
170 const std::string &/* service */) {
171 return test_->modem_3gpp_proxy_.release();
172 }
173
174 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
175 const std::string &/* path */,
176 const std::string &/* service */) {
177 return test_->modem_cdma_proxy_.release();
178 }
179
180 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
181 const std::string &/* path */,
182 const std::string &/* service */) {
183 return test_->modem_proxy_.release();
184 }
185
186 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
187 const std::string &/* path */,
188 const std::string &/* service */) {
189 return test_->modem_simple_proxy_.release();
190 }
191
192 virtual mm1::SimProxyInterface *CreateSimProxy(
193 const std::string &/* path */,
194 const std::string &/* service */) {
195 return test_->sim_proxy_.release();
196 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400197 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
198 const std::string &/* path */,
199 const std::string &/* service */) {
200 return test_->properties_proxy_.release();
201 }
Jason Glasgowef965562012-04-10 16:12:35 -0400202
203 private:
204 CellularCapabilityUniversalTest *test_;
205 };
206
207 NiceMockControl control_;
208 EventDispatcher dispatcher_;
209 MockMetrics metrics_;
210 MockGLib glib_;
211 MockManager manager_;
Jason Glasgowef965562012-04-10 16:12:35 -0400212 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
213 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
214 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
215 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
216 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400217 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400218 TestProxyFactory proxy_factory_;
219 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
220 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400221 mobile_provider_db *provider_db_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700222 CellularRefPtr cellular_;
223 MockCellularService *service_; // owned by cellular_
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400224 DBusPropertyMapsCallback scan_callback_; // saved for testing scan operations
Jason Glasgow14521872012-05-07 19:12:15 -0400225 DBusPathCallback connect_callback_; // saved for testing connect operations
Jason Glasgowef965562012-04-10 16:12:35 -0400226};
227
228const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400229const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
230const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
231 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
232 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400233
234TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400235 // Set up mock modem properties
236 DBusPropertiesMap modem_properties;
237 string operator_name = "TestOperator";
238 string operator_code = "001400";
239
240 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
241 writer().append_uint32(kAccessTechnologies);
242
243 ::DBus::Variant v;
244 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400245 ::DBus::Struct< uint32_t, bool > quality;
246 quality._1 = 90;
247 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400248 writer << quality;
249 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
250
251 // Set up mock modem 3gpp properties
252 DBusPropertiesMap modem3gpp_properties;
253 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
254 writer().append_uint32(0);
255 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
256 writer().append_string(kImei);
257
258 EXPECT_CALL(*modem_proxy_,
259 Enable(true, _, _, CellularCapability::kTimeoutEnable))
260 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
261 EXPECT_CALL(*properties_proxy_,
262 GetAll(MM_DBUS_INTERFACE_MODEM))
263 .WillOnce(Return(modem_properties));
264 EXPECT_CALL(*properties_proxy_,
265 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
266 .WillOnce(Return(modem3gpp_properties));
Jason Glasgowef965562012-04-10 16:12:35 -0400267
268 // After setup we lose pointers to the proxies, so it is hard to set
269 // expectations.
270 SetUp();
271
272 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400273 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400274 ResultCallback callback =
275 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
276 capability_->StartModem(&error, callback);
277 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400278 EXPECT_EQ(kImei, capability_->imei_);
279 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400280}
281
282TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
283 EXPECT_CALL(*modem_proxy_,
284 Enable(true, _, _, CellularCapability::kTimeoutEnable))
285 .WillOnce(
286 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
287 EXPECT_CALL(*this, TestCallback(IsFailure()));
288 ResultCallback callback =
289 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
290 SetUp();
291
292 Error error;
293 capability_->StartModem(&error, callback);
294 EXPECT_TRUE(error.IsSuccess());
295}
296
Jason Glasgow02401cc2012-05-16 10:35:37 -0400297TEST_F(CellularCapabilityUniversalTest, StopModem) {
298 // Save pointers to proxies before they are lost by the call to InitProxies
299 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
300 SetUp();
301 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
302 capability_->InitProxies();
303
304 Error error;
305 ResultCallback callback =
306 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
307 capability_->StopModem(&error, callback);
308 EXPECT_TRUE(error.IsSuccess());
309
310 ResultCallback disable_callback;
311 EXPECT_CALL(*modem_proxy,
312 Enable(false, _, _, CellularCapability::kTimeoutEnable))
313 .WillOnce(SaveArg<2>(&disable_callback));
314 dispatcher_.DispatchPendingEvents();
315
316 EXPECT_CALL(*this, TestCallback(IsSuccess()));
317 disable_callback.Run(Error(Error::kSuccess));
318}
319
320TEST_F(CellularCapabilityUniversalTest, StopModemConnected) {
321 // Save pointers to proxies before they are lost by the call to InitProxies
322 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
323 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
324 SetUp();
325 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
326 capability_->InitProxies();
327
328 ResultCallback disconnect_callback;
329 Error error;
330 ResultCallback callback =
331 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
332 EXPECT_CALL(*modem_simple_proxy,
333 Disconnect(::DBus::Path("/"), _, _,
334 CellularCapability::kTimeoutDefault))
335 .WillOnce(SaveArg<2>(&disconnect_callback));
Thieu Led0012052012-07-25 16:09:09 -0700336 capability_->cellular()->modem_state_ = Cellular::kModemStateConnected;
Jason Glasgow02401cc2012-05-16 10:35:37 -0400337 capability_->StopModem(&error, callback);
338 EXPECT_TRUE(error.IsSuccess());
339
340 ResultCallback disable_callback;
341 EXPECT_CALL(*modem_proxy,
342 Enable(false, _, _, CellularCapability::kTimeoutEnable))
343 .WillOnce(SaveArg<2>(&disable_callback));
344 disconnect_callback.Run(Error(Error::kSuccess));
345
346 EXPECT_CALL(*this, TestCallback(IsSuccess()));
347 disable_callback.Run(Error(Error::kSuccess));
348}
349
Thieu Le5d6864a2012-07-20 11:43:51 -0700350TEST_F(CellularCapabilityUniversalTest, DisconnectModemNoBearer) {
351 Error error;
352 ResultCallback disconnect_callback;
Thieu Le3d275392012-07-20 15:32:58 -0700353 EXPECT_CALL(*modem_simple_proxy_,
Thieu Le5d6864a2012-07-20 11:43:51 -0700354 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
355 .Times(0);
356 capability_->Disconnect(&error, disconnect_callback);
357}
358
Thieu Le3d275392012-07-20 15:32:58 -0700359TEST_F(CellularCapabilityUniversalTest, DisconnectNoProxy) {
360 Error error;
361 ResultCallback disconnect_callback;
362 capability_->bearer_path_ = "/foo";
363 EXPECT_CALL(*modem_simple_proxy_,
364 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
365 .Times(0);
366 ReleaseCapabilityProxies();
367 capability_->Disconnect(&error, disconnect_callback);
368}
369
Jason Glasgowaf583282012-04-18 15:18:22 -0400370TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
371 // Set up mock modem properties
372 DBusPropertiesMap modem_properties;
373 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
374 writer().append_uint32(kAccessTechnologies);
375 modem_properties[MM_MODEM_PROPERTY_SIM].
376 writer().append_path(kSimPath);
377
378 // Set up mock modem 3gpp properties
379 DBusPropertiesMap modem3gpp_properties;
380 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
381 writer().append_uint32(0);
382 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
383 writer().append_string(kImei);
384
385 // Set up mock modem sim properties
386 DBusPropertiesMap sim_properties;
387
388 // After setup we lose pointers to the proxies, so it is hard to set
389 // expectations.
390 EXPECT_CALL(*properties_proxy_,
391 GetAll(MM_DBUS_INTERFACE_SIM))
392 .WillOnce(Return(sim_properties));
393
394 SetUp();
395
396 EXPECT_EQ("", capability_->imei_);
397 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
398 capability_->access_technologies_);
399 EXPECT_FALSE(capability_->sim_proxy_.get());
Jason Glasgowbad114b2012-05-21 15:24:16 -0400400 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
401 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm));
Jason Glasgowaf583282012-04-18 15:18:22 -0400402 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
403 modem_properties, vector<string>());
404 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
405 EXPECT_EQ(kSimPath, capability_->sim_path_);
406 EXPECT_TRUE(capability_->sim_proxy_.get());
407
408 // Changing properties on wrong interface will not have an effect
409 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
410 modem3gpp_properties,
411 vector<string>());
412 EXPECT_EQ("", capability_->imei_);
413
414 // Changing properties on the right interface gets reflected in the
415 // capabilities object
416 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
417 modem3gpp_properties,
418 vector<string>());
419 EXPECT_EQ(kImei, capability_->imei_);
Jason Glasgowbad114b2012-05-21 15:24:16 -0400420
421 // Expect to see changes when the family changes
422 modem_properties.clear();
423 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
424 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
425 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
426 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyCdma)).
427 Times(1);
428 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
429 modem_properties,
430 vector<string>());
431 // Back to LTE
432 modem_properties.clear();
433 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
434 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE);
435 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
436 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm)).
437 Times(1);
438 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
439 modem_properties,
440 vector<string>());
441
442 // LTE & CDMA - the device adaptor should not be called!
443 modem_properties.clear();
444 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
445 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE |
446 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
447 EXPECT_CALL(*device_adaptor_, EmitStringChanged(_, _)).Times(0);
448 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
449 modem_properties,
450 vector<string>());
Jason Glasgowaf583282012-04-18 15:18:22 -0400451}
452
453TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
454 // Set up mock modem properties
455 DBusPropertiesMap modem_properties;
456 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
457
458 // Set up mock modem sim properties
459 const char kImsi[] = "310100000001";
460 DBusPropertiesMap sim_properties;
461 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
462
463 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
464 .WillOnce(Return(sim_properties));
465
466 // After setup we lose pointers to the proxies, so it is hard to set
467 // expectations.
468 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400469 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400470
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400471 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
472 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
473 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400474 EXPECT_FALSE(capability_->sim_proxy_.get());
475 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
476 modem_properties, vector<string>());
477 EXPECT_EQ(kSimPath, capability_->sim_path_);
478 EXPECT_TRUE(capability_->sim_proxy_.get());
479 EXPECT_EQ(kImsi, capability_->imsi_);
480
481 // Updating the SIM
482 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400483 const char kCountry[] = "us";
484 const char kCode[] = "310160";
485 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400486 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400487 const char kOperatorIdentifier[] = "310240";
488 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400489 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
490 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
491 append_string(kSimIdentifier);
492 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
493 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400494 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
495 new_properties,
496 vector<string>());
497 EXPECT_EQ(kNewImsi, capability_->imsi_);
498 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
499 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400500 EXPECT_EQ("", capability_->spn_);
501 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
502 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
503 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
504 EXPECT_EQ(4, capability_->apn_list_.size());
505
506 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
507 append_string(kOperatorName);
508 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
509 new_properties,
510 vector<string>());
511 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400512 EXPECT_EQ(kOperatorName, capability_->spn_);
513}
514
Gary Morainceba6aa2012-05-03 10:28:26 -0700515MATCHER_P(SizeIs, value, "") {
516 return static_cast<size_t>(value) == arg.size();
517}
518
519// Validates that OnScanReply does not crash with a null callback.
520TEST_F(CellularCapabilityUniversalTest, ScanWithNullCallback) {
521 Error error;
522 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
523 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeScan));
524 EXPECT_CALL(*device_adaptor_,
525 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
526 SizeIs(0)));
527 Set3gppProxy();
528 capability_->Scan(&error, ResultCallback());
529 EXPECT_TRUE(error.IsSuccess());
530}
531
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400532// Validates that the scanning property is updated
533TEST_F(CellularCapabilityUniversalTest, Scan) {
534 Error error;
535
536 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
537 .WillRepeatedly(SaveArg<1>(&scan_callback_));
538 EXPECT_CALL(*device_adaptor_,
539 EmitBoolChanged(flimflam::kScanningProperty, true));
540 Set3gppProxy();
541 capability_->Scan(&error, ResultCallback());
542 EXPECT_TRUE(capability_->scanning_);
543
544 // Simulate the completion of the scan with 2 networks in the results.
545 EXPECT_CALL(*device_adaptor_,
546 EmitBoolChanged(flimflam::kScanningProperty, false));
547 EXPECT_CALL(*device_adaptor_,
548 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
549 SizeIs(2)));
550 vector<DBusPropertiesMap> results;
551 const char kScanID0[] = "testID0";
552 const char kScanID1[] = "testID1";
553 results.push_back(DBusPropertiesMap());
554 results[0][CellularCapabilityUniversal::kOperatorLongProperty].
555 writer().append_string(kScanID0);
556 results.push_back(DBusPropertiesMap());
557 results[1][CellularCapabilityUniversal::kOperatorLongProperty].
558 writer().append_string(kScanID1);
559 scan_callback_.Run(results, error);
560 EXPECT_FALSE(capability_->scanning_);
561
562 // Simulate the completion of the scan with no networks in the results.
563 EXPECT_CALL(*device_adaptor_,
564 EmitBoolChanged(flimflam::kScanningProperty, true));
565 capability_->Scan(&error, ResultCallback());
566 EXPECT_TRUE(capability_->scanning_);
567 EXPECT_CALL(*device_adaptor_,
568 EmitBoolChanged(flimflam::kScanningProperty, false));
569 EXPECT_CALL(*device_adaptor_,
570 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
571 SizeIs(0)));
572 scan_callback_.Run(vector<DBusPropertiesMap>(), Error());
573 EXPECT_FALSE(capability_->scanning_);
574}
575
576// Validates expected property updates when scan fails
577TEST_F(CellularCapabilityUniversalTest, ScanFailure) {
578 Error error;
579
580 // Test immediate error
581 {
582 InSequence seq;
583 EXPECT_CALL(*modem_3gpp_proxy_,
584 Scan(_, _, CellularCapability::kTimeoutScan))
585 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::ScanError));
586 EXPECT_CALL(*modem_3gpp_proxy_,
587 Scan(_, _, CellularCapability::kTimeoutScan))
588 .WillOnce(SaveArg<1>(&scan_callback_));
589 }
590 Set3gppProxy();
591 capability_->Scan(&error, ResultCallback());
592 EXPECT_FALSE(capability_->scanning_);
593 EXPECT_TRUE(error.IsFailure());
594
595 // Initiate a scan
596 error.Populate(Error::kSuccess);
597 EXPECT_CALL(*device_adaptor_,
598 EmitBoolChanged(flimflam::kScanningProperty, true));
599 capability_->Scan(&error, ResultCallback());
600 EXPECT_TRUE(capability_->scanning_);
601 EXPECT_TRUE(error.IsSuccess());
602
603 // Validate that error is returned if Scan is called while already scanning.
604 capability_->Scan(&error, ResultCallback());
605 EXPECT_TRUE(capability_->scanning_);
606 EXPECT_TRUE(error.IsFailure());
607
608 // Validate that signals are emitted even if an error is reported.
609 capability_->found_networks_.clear();
610 capability_->found_networks_.push_back(Stringmap());
611 EXPECT_CALL(*device_adaptor_,
612 EmitBoolChanged(flimflam::kScanningProperty, false));
613 EXPECT_CALL(*device_adaptor_,
614 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
615 SizeIs(0)));
616 vector<DBusPropertiesMap> results;
617 scan_callback_.Run(results, Error(Error::kOperationFailed));
618 EXPECT_FALSE(capability_->scanning_);
619}
620
Jason Glasgow14521872012-05-07 19:12:15 -0400621// Validates expected behavior of Connect function
622TEST_F(CellularCapabilityUniversalTest, Connect) {
623 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
624 SetSimpleProxy();
625 Error error;
626 DBusPropertiesMap properties;
627 capability_->apn_try_list_.clear();
628 ResultCallback callback =
629 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
630 DBus::Path bearer("/foo");
631
632 // Test connect failures
633 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
634 .WillOnce(SaveArg<2>(&connect_callback_));
635 capability_->Connect(properties, &error, callback);
636 EXPECT_TRUE(error.IsSuccess());
637 EXPECT_CALL(*this, TestCallback(IsFailure()));
638 EXPECT_CALL(*service_, ClearLastGoodApn());
639 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
640
641 // Test connect success
642 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
643 .WillOnce(SaveArg<2>(&connect_callback_));
644 capability_->Connect(properties, &error, callback);
645 EXPECT_TRUE(error.IsSuccess());
646 EXPECT_CALL(*this, TestCallback(IsSuccess()));
647 connect_callback_.Run(bearer, Error(Error::kSuccess));
Jason Glasgow7234ec32012-05-23 16:01:21 -0400648
649 // Test connect failures without a service. Make sure that shill
650 // does not crash if the connect failed and there is no
651 // CellularService object. This can happen if the modem is enabled
652 // and then quickly disabled.
653 cellular_->service_ = NULL;
654 EXPECT_FALSE(capability_->cellular()->service());
655 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
656 .WillOnce(SaveArg<2>(&connect_callback_));
657 capability_->Connect(properties, &error, callback);
658 EXPECT_TRUE(error.IsSuccess());
659 EXPECT_CALL(*this, TestCallback(IsFailure()));
660 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
Jason Glasgow14521872012-05-07 19:12:15 -0400661}
662
663// Validates Connect iterates over APNs
664TEST_F(CellularCapabilityUniversalTest, ConnectApns) {
665 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
666 SetSimpleProxy();
667 Error error;
668 DBusPropertiesMap properties;
669 capability_->apn_try_list_.clear();
670 ResultCallback callback =
671 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
672 DBus::Path bearer("/bearer0");
673
674 const char apn_name_foo[] = "foo";
675 const char apn_name_bar[] = "bar";
676 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_foo), _, _, _))
677 .WillOnce(SaveArg<2>(&connect_callback_));
678 Stringmap apn1;
679 apn1[flimflam::kApnProperty] = apn_name_foo;
680 capability_->apn_try_list_.push_back(apn1);
681 Stringmap apn2;
682 apn2[flimflam::kApnProperty] = apn_name_bar;
683 capability_->apn_try_list_.push_back(apn2);
684 capability_->FillConnectPropertyMap(&properties);
685 capability_->Connect(properties, &error, callback);
686 EXPECT_TRUE(error.IsSuccess());
687
688 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_bar), _, _, _))
689 .WillOnce(SaveArg<2>(&connect_callback_));
690 EXPECT_CALL(*service_, ClearLastGoodApn());
691 connect_callback_.Run(bearer, Error(Error::kInvalidApn));
692
693 EXPECT_CALL(*service_, SetLastGoodApn(apn2));
694 EXPECT_CALL(*this, TestCallback(IsSuccess()));
695 connect_callback_.Run(bearer, Error(Error::kSuccess));
696}
697
Jason Glasgow9f09aef2012-05-08 16:26:55 -0400698// Validates GetTypeString and AccessTechnologyToTechnologyFamily
699TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
700 const int gsm_technologies[] = {
701 MM_MODEM_ACCESS_TECHNOLOGY_LTE,
702 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
703 MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
704 MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
705 MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
706 MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
707 MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
708 MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
709 MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
710 MM_MODEM_ACCESS_TECHNOLOGY_GSM,
711 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
712 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
713 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
714 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
715 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
716 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
717 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
718 };
719 for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
720 capability_->access_technologies_ = gsm_technologies[i];
721 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
722 }
723 const int cdma_technologies[] = {
724 MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
725 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
726 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
727 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
728 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
729 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
730 };
731 for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
732 capability_->access_technologies_ = cdma_technologies[i];
733 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
734 }
735 capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
736 ASSERT_EQ(capability_->GetTypeString(), "");
737}
738
Jason Glasgowef965562012-04-10 16:12:35 -0400739} // namespace shill