blob: 23c64c8a03c8204585c87e7dc1ef81fb52330458 [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>
Darin Petkova4ca3c32012-08-17 16:05:24 +020011#include <base/stringprintf.h>
Jason Glasgowef965562012-04-10 16:12:35 -040012#include <chromeos/dbus/service_constants.h>
13#include <gtest/gtest.h>
14#include <mobile_provider.h>
Ben Chanf6120e92012-06-28 18:56:17 -070015#include <ModemManager/ModemManager-names.h>
Jason Glasgowef965562012-04-10 16:12:35 -040016
17#include "shill/cellular.h"
18#include "shill/cellular_service.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040019#include "shill/dbus_adaptor.h"
Jason Glasgowef965562012-04-10 16:12:35 -040020#include "shill/error.h"
21#include "shill/event_dispatcher.h"
22#include "shill/mock_adaptors.h"
Jason Glasgow14521872012-05-07 19:12:15 -040023#include "shill/mock_cellular_service.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040024#include "shill/mock_dbus_properties_proxy.h"
Jason Glasgowef965562012-04-10 16:12:35 -040025#include "shill/mock_glib.h"
26#include "shill/mock_manager.h"
27#include "shill/mock_metrics.h"
28#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
29#include "shill/mock_mm1_modem_modemcdma_proxy.h"
30#include "shill/mock_mm1_modem_proxy.h"
31#include "shill/mock_mm1_modem_simple_proxy.h"
32#include "shill/mock_mm1_sim_proxy.h"
33#include "shill/mock_profile.h"
34#include "shill/mock_rtnl_handler.h"
35#include "shill/nice_mock_control.h"
36#include "shill/proxy_factory.h"
37
38using base::Bind;
Darin Petkova4ca3c32012-08-17 16:05:24 +020039using base::StringPrintf;
Jason Glasgowef965562012-04-10 16:12:35 -040040using base::Unretained;
41using std::string;
Nathan Williams4b7c2a82012-04-13 15:19:47 -040042using std::vector;
Jason Glasgowef965562012-04-10 16:12:35 -040043using testing::InSequence;
44using testing::NiceMock;
45using testing::Return;
Jason Glasgowcd0349c2012-05-03 23:32:15 -040046using testing::SaveArg;
Jason Glasgowef965562012-04-10 16:12:35 -040047using testing::_;
48
49namespace shill {
50
51MATCHER(IsSuccess, "") {
52 return arg.IsSuccess();
53}
54MATCHER(IsFailure, "") {
55 return arg.IsFailure();
56}
Jason Glasgow14521872012-05-07 19:12:15 -040057MATCHER_P(HasApn, expected_apn, "") {
58 string apn;
59 return (DBusProperties::GetString(arg,
60 CellularCapabilityUniversal::kConnectApn,
61 &apn) &&
62 apn == expected_apn);
63}
Jason Glasgowef965562012-04-10 16:12:35 -040064
65class CellularCapabilityUniversalTest : public testing::Test {
66 public:
67 CellularCapabilityUniversalTest()
68 : manager_(&control_, &dispatcher_, &metrics_, &glib_),
Ben Chan3ecdf822012-08-06 12:29:23 -070069 modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
70 modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
71 modem_proxy_(new mm1::MockModemProxy()),
72 modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
73 sim_proxy_(new mm1::MockSimProxy()),
74 properties_proxy_(new MockDBusPropertiesProxy()),
75 proxy_factory_(this),
76 capability_(NULL),
77 device_adaptor_(NULL),
78 provider_db_(NULL),
Jason Glasgowef965562012-04-10 16:12:35 -040079 cellular_(new Cellular(&control_,
80 &dispatcher_,
81 NULL,
82 &manager_,
83 "",
84 "",
85 0,
86 Cellular::kTypeUniversal,
87 "",
88 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040089 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070090 NULL,
91 &proxy_factory_)),
Jason Glasgow14521872012-05-07 19:12:15 -040092 service_(new MockCellularService(&control_,
93 &dispatcher_,
94 &metrics_,
95 &manager_,
Ben Chan3ecdf822012-08-06 12:29:23 -070096 cellular_)) {}
Jason Glasgowef965562012-04-10 16:12:35 -040097
98 virtual ~CellularCapabilityUniversalTest() {
99 cellular_->service_ = NULL;
100 capability_ = NULL;
101 device_adaptor_ = NULL;
Darin Petkovb4fccd22012-08-10 11:59:26 +0200102 if (provider_db_) {
103 mobile_provider_close_db(provider_db_);
104 provider_db_ = NULL;
105 }
Jason Glasgowef965562012-04-10 16:12:35 -0400106 }
107
108 virtual void SetUp() {
109 capability_ = dynamic_cast<CellularCapabilityUniversal *>(
110 cellular_->capability_.get());
Jason Glasgowef965562012-04-10 16:12:35 -0400111 device_adaptor_ =
112 dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
Jason Glasgow14521872012-05-07 19:12:15 -0400113 cellular_->service_ = service_;
Jason Glasgowef965562012-04-10 16:12:35 -0400114 }
115
116 virtual void TearDown() {
117 capability_->proxy_factory_ = NULL;
118 }
119
Darin Petkova4ca3c32012-08-17 16:05:24 +0200120 void SetService() {
121 cellular_->service_ = new CellularService(
122 &control_, &dispatcher_, &metrics_, NULL, cellular_);
123 }
124
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400125 void InitProviderDB() {
126 const char kTestMobileProviderDBPath[] = "provider_db_unittest.bfd";
127
128 provider_db_ = mobile_provider_open_db(kTestMobileProviderDBPath);
129 ASSERT_TRUE(provider_db_);
130 cellular_->provider_db_ = provider_db_;
131 }
132
Jason Glasgowef965562012-04-10 16:12:35 -0400133 void InvokeEnable(bool enable, Error *error,
134 const ResultCallback &callback, int timeout) {
135 callback.Run(Error());
136 }
137 void InvokeEnableFail(bool enable, Error *error,
138 const ResultCallback &callback, int timeout) {
139 callback.Run(Error(Error::kOperationFailed));
140 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400141 void InvokeRegister(const string &operator_id, Error *error,
142 const ResultCallback &callback, int timeout) {
143 callback.Run(Error());
144 }
145
Gary Morainceba6aa2012-05-03 10:28:26 -0700146 void InvokeScan(Error *error, const DBusPropertyMapsCallback &callback,
147 int timeout) {
148 callback.Run(CellularCapabilityUniversal::ScanResults(), Error());
149 }
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400150 void ScanError(Error *error, const DBusPropertyMapsCallback &callback,
151 int timeout) {
152 error->Populate(Error::kOperationFailed);
153 }
Gary Morainceba6aa2012-05-03 10:28:26 -0700154
155 void Set3gppProxy() {
156 capability_->modem_3gpp_proxy_.reset(modem_3gpp_proxy_.release());
157 }
158
Jason Glasgow14521872012-05-07 19:12:15 -0400159 void SetSimpleProxy() {
160 capability_->modem_simple_proxy_.reset(modem_simple_proxy_.release());
161 }
162
Thieu Le3d275392012-07-20 15:32:58 -0700163 void ReleaseCapabilityProxies() {
164 capability_->ReleaseProxies();
165 }
166
Jason Glasgowef965562012-04-10 16:12:35 -0400167 MOCK_METHOD1(TestCallback, void(const Error &error));
168
169 protected:
170 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400171 static const char kSimPath[];
172 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400173
174 class TestProxyFactory : public ProxyFactory {
175 public:
176 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
177 test_(test) {}
178
179 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
180 const std::string &/* path */,
181 const std::string &/* service */) {
182 return test_->modem_3gpp_proxy_.release();
183 }
184
185 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
186 const std::string &/* path */,
187 const std::string &/* service */) {
188 return test_->modem_cdma_proxy_.release();
189 }
190
191 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
192 const std::string &/* path */,
193 const std::string &/* service */) {
194 return test_->modem_proxy_.release();
195 }
196
197 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
198 const std::string &/* path */,
199 const std::string &/* service */) {
200 return test_->modem_simple_proxy_.release();
201 }
202
203 virtual mm1::SimProxyInterface *CreateSimProxy(
204 const std::string &/* path */,
205 const std::string &/* service */) {
206 return test_->sim_proxy_.release();
207 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400208 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
209 const std::string &/* path */,
210 const std::string &/* service */) {
211 return test_->properties_proxy_.release();
212 }
Jason Glasgowef965562012-04-10 16:12:35 -0400213
214 private:
215 CellularCapabilityUniversalTest *test_;
216 };
217
218 NiceMockControl control_;
219 EventDispatcher dispatcher_;
220 MockMetrics metrics_;
221 MockGLib glib_;
222 MockManager manager_;
Jason Glasgowef965562012-04-10 16:12:35 -0400223 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
224 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
225 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
226 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
227 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400228 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400229 TestProxyFactory proxy_factory_;
230 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
231 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400232 mobile_provider_db *provider_db_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700233 CellularRefPtr cellular_;
234 MockCellularService *service_; // owned by cellular_
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400235 DBusPropertyMapsCallback scan_callback_; // saved for testing scan operations
Jason Glasgow14521872012-05-07 19:12:15 -0400236 DBusPathCallback connect_callback_; // saved for testing connect operations
Jason Glasgowef965562012-04-10 16:12:35 -0400237};
238
239const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400240const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
241const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
242 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
243 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400244
245TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400246 // Set up mock modem properties
247 DBusPropertiesMap modem_properties;
248 string operator_name = "TestOperator";
249 string operator_code = "001400";
250
251 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
252 writer().append_uint32(kAccessTechnologies);
253
254 ::DBus::Variant v;
255 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400256 ::DBus::Struct< uint32_t, bool > quality;
257 quality._1 = 90;
258 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400259 writer << quality;
260 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
261
262 // Set up mock modem 3gpp properties
263 DBusPropertiesMap modem3gpp_properties;
264 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
265 writer().append_uint32(0);
266 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
267 writer().append_string(kImei);
268
269 EXPECT_CALL(*modem_proxy_,
270 Enable(true, _, _, CellularCapability::kTimeoutEnable))
271 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
272 EXPECT_CALL(*properties_proxy_,
273 GetAll(MM_DBUS_INTERFACE_MODEM))
274 .WillOnce(Return(modem_properties));
275 EXPECT_CALL(*properties_proxy_,
276 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
277 .WillOnce(Return(modem3gpp_properties));
Jason Glasgowef965562012-04-10 16:12:35 -0400278
279 // After setup we lose pointers to the proxies, so it is hard to set
280 // expectations.
281 SetUp();
282
283 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400284 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400285 ResultCallback callback =
286 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
287 capability_->StartModem(&error, callback);
288 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400289 EXPECT_EQ(kImei, capability_->imei_);
290 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400291}
292
293TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
294 EXPECT_CALL(*modem_proxy_,
295 Enable(true, _, _, CellularCapability::kTimeoutEnable))
296 .WillOnce(
297 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
298 EXPECT_CALL(*this, TestCallback(IsFailure()));
299 ResultCallback callback =
300 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
301 SetUp();
302
303 Error error;
304 capability_->StartModem(&error, callback);
305 EXPECT_TRUE(error.IsSuccess());
306}
307
Jason Glasgow02401cc2012-05-16 10:35:37 -0400308TEST_F(CellularCapabilityUniversalTest, StopModem) {
309 // Save pointers to proxies before they are lost by the call to InitProxies
310 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
311 SetUp();
312 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
313 capability_->InitProxies();
314
315 Error error;
316 ResultCallback callback =
317 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
318 capability_->StopModem(&error, callback);
319 EXPECT_TRUE(error.IsSuccess());
320
321 ResultCallback disable_callback;
322 EXPECT_CALL(*modem_proxy,
323 Enable(false, _, _, CellularCapability::kTimeoutEnable))
324 .WillOnce(SaveArg<2>(&disable_callback));
325 dispatcher_.DispatchPendingEvents();
326
327 EXPECT_CALL(*this, TestCallback(IsSuccess()));
328 disable_callback.Run(Error(Error::kSuccess));
329}
330
331TEST_F(CellularCapabilityUniversalTest, StopModemConnected) {
332 // Save pointers to proxies before they are lost by the call to InitProxies
333 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
334 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
335 SetUp();
336 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
337 capability_->InitProxies();
338
339 ResultCallback disconnect_callback;
340 Error error;
341 ResultCallback callback =
342 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
343 EXPECT_CALL(*modem_simple_proxy,
344 Disconnect(::DBus::Path("/"), _, _,
345 CellularCapability::kTimeoutDefault))
346 .WillOnce(SaveArg<2>(&disconnect_callback));
Thieu Led0012052012-07-25 16:09:09 -0700347 capability_->cellular()->modem_state_ = Cellular::kModemStateConnected;
Jason Glasgow02401cc2012-05-16 10:35:37 -0400348 capability_->StopModem(&error, callback);
349 EXPECT_TRUE(error.IsSuccess());
350
351 ResultCallback disable_callback;
352 EXPECT_CALL(*modem_proxy,
353 Enable(false, _, _, CellularCapability::kTimeoutEnable))
354 .WillOnce(SaveArg<2>(&disable_callback));
355 disconnect_callback.Run(Error(Error::kSuccess));
356
357 EXPECT_CALL(*this, TestCallback(IsSuccess()));
358 disable_callback.Run(Error(Error::kSuccess));
359}
360
Thieu Le5d6864a2012-07-20 11:43:51 -0700361TEST_F(CellularCapabilityUniversalTest, DisconnectModemNoBearer) {
362 Error error;
363 ResultCallback disconnect_callback;
Thieu Le3d275392012-07-20 15:32:58 -0700364 EXPECT_CALL(*modem_simple_proxy_,
Thieu Le5d6864a2012-07-20 11:43:51 -0700365 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
366 .Times(0);
367 capability_->Disconnect(&error, disconnect_callback);
368}
369
Thieu Le3d275392012-07-20 15:32:58 -0700370TEST_F(CellularCapabilityUniversalTest, DisconnectNoProxy) {
371 Error error;
372 ResultCallback disconnect_callback;
373 capability_->bearer_path_ = "/foo";
374 EXPECT_CALL(*modem_simple_proxy_,
375 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
376 .Times(0);
377 ReleaseCapabilityProxies();
378 capability_->Disconnect(&error, disconnect_callback);
379}
380
Jason Glasgowaf583282012-04-18 15:18:22 -0400381TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
382 // Set up mock modem properties
383 DBusPropertiesMap modem_properties;
384 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
385 writer().append_uint32(kAccessTechnologies);
386 modem_properties[MM_MODEM_PROPERTY_SIM].
387 writer().append_path(kSimPath);
388
389 // Set up mock modem 3gpp properties
390 DBusPropertiesMap modem3gpp_properties;
391 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
392 writer().append_uint32(0);
393 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
394 writer().append_string(kImei);
395
396 // Set up mock modem sim properties
397 DBusPropertiesMap sim_properties;
398
399 // After setup we lose pointers to the proxies, so it is hard to set
400 // expectations.
401 EXPECT_CALL(*properties_proxy_,
402 GetAll(MM_DBUS_INTERFACE_SIM))
403 .WillOnce(Return(sim_properties));
404
405 SetUp();
406
407 EXPECT_EQ("", capability_->imei_);
408 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
409 capability_->access_technologies_);
410 EXPECT_FALSE(capability_->sim_proxy_.get());
Jason Glasgowbad114b2012-05-21 15:24:16 -0400411 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
412 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm));
Jason Glasgowaf583282012-04-18 15:18:22 -0400413 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
414 modem_properties, vector<string>());
415 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
416 EXPECT_EQ(kSimPath, capability_->sim_path_);
417 EXPECT_TRUE(capability_->sim_proxy_.get());
418
419 // Changing properties on wrong interface will not have an effect
420 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
421 modem3gpp_properties,
422 vector<string>());
423 EXPECT_EQ("", capability_->imei_);
424
425 // Changing properties on the right interface gets reflected in the
426 // capabilities object
427 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
428 modem3gpp_properties,
429 vector<string>());
430 EXPECT_EQ(kImei, capability_->imei_);
Jason Glasgowbad114b2012-05-21 15:24:16 -0400431
432 // Expect to see changes when the family changes
433 modem_properties.clear();
434 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
435 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
436 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
437 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyCdma)).
438 Times(1);
439 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
440 modem_properties,
441 vector<string>());
442 // Back to LTE
443 modem_properties.clear();
444 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
445 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE);
446 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
447 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm)).
448 Times(1);
449 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
450 modem_properties,
451 vector<string>());
452
453 // LTE & CDMA - the device adaptor should not be called!
454 modem_properties.clear();
455 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
456 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE |
457 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
458 EXPECT_CALL(*device_adaptor_, EmitStringChanged(_, _)).Times(0);
459 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
460 modem_properties,
461 vector<string>());
Jason Glasgowaf583282012-04-18 15:18:22 -0400462}
463
464TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
465 // Set up mock modem properties
466 DBusPropertiesMap modem_properties;
467 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
468
469 // Set up mock modem sim properties
470 const char kImsi[] = "310100000001";
471 DBusPropertiesMap sim_properties;
472 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
473
474 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
475 .WillOnce(Return(sim_properties));
476
477 // After setup we lose pointers to the proxies, so it is hard to set
478 // expectations.
479 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400480 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400481
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400482 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
483 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
484 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400485 EXPECT_FALSE(capability_->sim_proxy_.get());
486 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
487 modem_properties, vector<string>());
488 EXPECT_EQ(kSimPath, capability_->sim_path_);
489 EXPECT_TRUE(capability_->sim_proxy_.get());
490 EXPECT_EQ(kImsi, capability_->imsi_);
491
492 // Updating the SIM
493 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400494 const char kCountry[] = "us";
495 const char kCode[] = "310160";
496 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400497 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400498 const char kOperatorIdentifier[] = "310240";
499 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400500 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
501 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
502 append_string(kSimIdentifier);
503 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
504 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400505 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
506 new_properties,
507 vector<string>());
508 EXPECT_EQ(kNewImsi, capability_->imsi_);
509 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
510 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400511 EXPECT_EQ("", capability_->spn_);
512 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
513 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
514 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
515 EXPECT_EQ(4, capability_->apn_list_.size());
516
517 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
518 append_string(kOperatorName);
519 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
520 new_properties,
521 vector<string>());
522 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400523 EXPECT_EQ(kOperatorName, capability_->spn_);
524}
525
Gary Morainceba6aa2012-05-03 10:28:26 -0700526MATCHER_P(SizeIs, value, "") {
527 return static_cast<size_t>(value) == arg.size();
528}
529
530// Validates that OnScanReply does not crash with a null callback.
531TEST_F(CellularCapabilityUniversalTest, ScanWithNullCallback) {
532 Error error;
533 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
534 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeScan));
535 EXPECT_CALL(*device_adaptor_,
536 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
537 SizeIs(0)));
538 Set3gppProxy();
539 capability_->Scan(&error, ResultCallback());
540 EXPECT_TRUE(error.IsSuccess());
541}
542
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400543// Validates that the scanning property is updated
544TEST_F(CellularCapabilityUniversalTest, Scan) {
545 Error error;
546
547 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
548 .WillRepeatedly(SaveArg<1>(&scan_callback_));
549 EXPECT_CALL(*device_adaptor_,
550 EmitBoolChanged(flimflam::kScanningProperty, true));
551 Set3gppProxy();
552 capability_->Scan(&error, ResultCallback());
553 EXPECT_TRUE(capability_->scanning_);
554
555 // Simulate the completion of the scan with 2 networks in the results.
556 EXPECT_CALL(*device_adaptor_,
557 EmitBoolChanged(flimflam::kScanningProperty, false));
558 EXPECT_CALL(*device_adaptor_,
559 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
560 SizeIs(2)));
561 vector<DBusPropertiesMap> results;
562 const char kScanID0[] = "testID0";
563 const char kScanID1[] = "testID1";
564 results.push_back(DBusPropertiesMap());
565 results[0][CellularCapabilityUniversal::kOperatorLongProperty].
566 writer().append_string(kScanID0);
567 results.push_back(DBusPropertiesMap());
568 results[1][CellularCapabilityUniversal::kOperatorLongProperty].
569 writer().append_string(kScanID1);
570 scan_callback_.Run(results, error);
571 EXPECT_FALSE(capability_->scanning_);
572
573 // Simulate the completion of the scan with no networks in the results.
574 EXPECT_CALL(*device_adaptor_,
575 EmitBoolChanged(flimflam::kScanningProperty, true));
576 capability_->Scan(&error, ResultCallback());
577 EXPECT_TRUE(capability_->scanning_);
578 EXPECT_CALL(*device_adaptor_,
579 EmitBoolChanged(flimflam::kScanningProperty, false));
580 EXPECT_CALL(*device_adaptor_,
581 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
582 SizeIs(0)));
583 scan_callback_.Run(vector<DBusPropertiesMap>(), Error());
584 EXPECT_FALSE(capability_->scanning_);
585}
586
587// Validates expected property updates when scan fails
588TEST_F(CellularCapabilityUniversalTest, ScanFailure) {
589 Error error;
590
591 // Test immediate error
592 {
593 InSequence seq;
594 EXPECT_CALL(*modem_3gpp_proxy_,
595 Scan(_, _, CellularCapability::kTimeoutScan))
596 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::ScanError));
597 EXPECT_CALL(*modem_3gpp_proxy_,
598 Scan(_, _, CellularCapability::kTimeoutScan))
599 .WillOnce(SaveArg<1>(&scan_callback_));
600 }
601 Set3gppProxy();
602 capability_->Scan(&error, ResultCallback());
603 EXPECT_FALSE(capability_->scanning_);
604 EXPECT_TRUE(error.IsFailure());
605
606 // Initiate a scan
607 error.Populate(Error::kSuccess);
608 EXPECT_CALL(*device_adaptor_,
609 EmitBoolChanged(flimflam::kScanningProperty, true));
610 capability_->Scan(&error, ResultCallback());
611 EXPECT_TRUE(capability_->scanning_);
612 EXPECT_TRUE(error.IsSuccess());
613
614 // Validate that error is returned if Scan is called while already scanning.
615 capability_->Scan(&error, ResultCallback());
616 EXPECT_TRUE(capability_->scanning_);
617 EXPECT_TRUE(error.IsFailure());
618
619 // Validate that signals are emitted even if an error is reported.
620 capability_->found_networks_.clear();
621 capability_->found_networks_.push_back(Stringmap());
622 EXPECT_CALL(*device_adaptor_,
623 EmitBoolChanged(flimflam::kScanningProperty, false));
624 EXPECT_CALL(*device_adaptor_,
625 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
626 SizeIs(0)));
627 vector<DBusPropertiesMap> results;
628 scan_callback_.Run(results, Error(Error::kOperationFailed));
629 EXPECT_FALSE(capability_->scanning_);
630}
631
Jason Glasgow14521872012-05-07 19:12:15 -0400632// Validates expected behavior of Connect function
633TEST_F(CellularCapabilityUniversalTest, Connect) {
634 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
635 SetSimpleProxy();
636 Error error;
637 DBusPropertiesMap properties;
638 capability_->apn_try_list_.clear();
639 ResultCallback callback =
640 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
641 DBus::Path bearer("/foo");
642
643 // Test connect failures
644 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
645 .WillOnce(SaveArg<2>(&connect_callback_));
646 capability_->Connect(properties, &error, callback);
647 EXPECT_TRUE(error.IsSuccess());
648 EXPECT_CALL(*this, TestCallback(IsFailure()));
649 EXPECT_CALL(*service_, ClearLastGoodApn());
650 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
651
652 // Test connect success
653 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
654 .WillOnce(SaveArg<2>(&connect_callback_));
655 capability_->Connect(properties, &error, callback);
656 EXPECT_TRUE(error.IsSuccess());
657 EXPECT_CALL(*this, TestCallback(IsSuccess()));
658 connect_callback_.Run(bearer, Error(Error::kSuccess));
Jason Glasgow7234ec32012-05-23 16:01:21 -0400659
660 // Test connect failures without a service. Make sure that shill
661 // does not crash if the connect failed and there is no
662 // CellularService object. This can happen if the modem is enabled
663 // and then quickly disabled.
664 cellular_->service_ = NULL;
665 EXPECT_FALSE(capability_->cellular()->service());
666 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
667 .WillOnce(SaveArg<2>(&connect_callback_));
668 capability_->Connect(properties, &error, callback);
669 EXPECT_TRUE(error.IsSuccess());
670 EXPECT_CALL(*this, TestCallback(IsFailure()));
671 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
Jason Glasgow14521872012-05-07 19:12:15 -0400672}
673
674// Validates Connect iterates over APNs
675TEST_F(CellularCapabilityUniversalTest, ConnectApns) {
676 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
677 SetSimpleProxy();
678 Error error;
679 DBusPropertiesMap properties;
680 capability_->apn_try_list_.clear();
681 ResultCallback callback =
682 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
683 DBus::Path bearer("/bearer0");
684
685 const char apn_name_foo[] = "foo";
686 const char apn_name_bar[] = "bar";
687 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_foo), _, _, _))
688 .WillOnce(SaveArg<2>(&connect_callback_));
689 Stringmap apn1;
690 apn1[flimflam::kApnProperty] = apn_name_foo;
691 capability_->apn_try_list_.push_back(apn1);
692 Stringmap apn2;
693 apn2[flimflam::kApnProperty] = apn_name_bar;
694 capability_->apn_try_list_.push_back(apn2);
695 capability_->FillConnectPropertyMap(&properties);
696 capability_->Connect(properties, &error, callback);
697 EXPECT_TRUE(error.IsSuccess());
698
699 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_bar), _, _, _))
700 .WillOnce(SaveArg<2>(&connect_callback_));
701 EXPECT_CALL(*service_, ClearLastGoodApn());
702 connect_callback_.Run(bearer, Error(Error::kInvalidApn));
703
704 EXPECT_CALL(*service_, SetLastGoodApn(apn2));
705 EXPECT_CALL(*this, TestCallback(IsSuccess()));
706 connect_callback_.Run(bearer, Error(Error::kSuccess));
707}
708
Jason Glasgow9f09aef2012-05-08 16:26:55 -0400709// Validates GetTypeString and AccessTechnologyToTechnologyFamily
710TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
711 const int gsm_technologies[] = {
712 MM_MODEM_ACCESS_TECHNOLOGY_LTE,
713 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
714 MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
715 MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
716 MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
717 MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
718 MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
719 MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
720 MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
721 MM_MODEM_ACCESS_TECHNOLOGY_GSM,
722 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
723 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
724 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
725 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
726 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
727 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
728 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
729 };
730 for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
731 capability_->access_technologies_ = gsm_technologies[i];
732 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
733 }
734 const int cdma_technologies[] = {
735 MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
736 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
737 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
738 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
739 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
740 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
741 };
742 for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
743 capability_->access_technologies_ = cdma_technologies[i];
744 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
745 }
746 capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
747 ASSERT_EQ(capability_->GetTypeString(), "");
748}
749
Darin Petkovb4fccd22012-08-10 11:59:26 +0200750TEST_F(CellularCapabilityUniversalTest, SetHomeProvider) {
751 static const char kTestCarrier[] = "The Cellular Carrier";
752 static const char kCountry[] = "us";
753 static const char kCode[] = "310160";
754 capability_->imsi_ = "310240123456789";
755
756 capability_->SetHomeProvider(); // No mobile provider DB available.
757 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
758 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
759 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
760
761 InitProviderDB();
762 capability_->SetHomeProvider();
763 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
764 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
765 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
766 EXPECT_EQ(4, capability_->apn_list_.size());
767 ASSERT_TRUE(capability_->home_provider_);
768 EXPECT_FALSE(capability_->home_provider_->requires_roaming);
769
770 Cellular::Operator oper;
771 cellular_->set_home_provider(oper);
772 capability_->spn_ = kTestCarrier;
773 capability_->SetHomeProvider();
774 EXPECT_EQ(kTestCarrier, cellular_->home_provider().GetName());
775 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
776 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
777
778 static const char kCubic[] = "Cubic";
779 capability_->spn_ = kCubic;
780 capability_->SetHomeProvider();
781 EXPECT_EQ(kCubic, cellular_->home_provider().GetName());
782 EXPECT_EQ("", cellular_->home_provider().GetCode());
783 ASSERT_TRUE(capability_->home_provider_);
784 EXPECT_TRUE(capability_->home_provider_->requires_roaming);
785
786 static const char kCUBIC[] = "CUBIC";
787 capability_->spn_ = kCUBIC;
788 capability_->home_provider_ = NULL;
789 capability_->SetHomeProvider();
790 EXPECT_EQ(kCUBIC, cellular_->home_provider().GetName());
791 EXPECT_EQ("", cellular_->home_provider().GetCode());
792 ASSERT_TRUE(capability_->home_provider_);
793 EXPECT_TRUE(capability_->home_provider_->requires_roaming);
794}
795
Darin Petkova4ca3c32012-08-17 16:05:24 +0200796TEST_F(CellularCapabilityUniversalTest, UpdateOperatorInfo) {
797 static const char kOperatorName[] = "Swisscom";
798 InitProviderDB();
799 capability_->serving_operator_.SetCode("22801");
800 SetService();
801 capability_->UpdateOperatorInfo();
802 EXPECT_EQ(kOperatorName, capability_->serving_operator_.GetName());
803 EXPECT_EQ("ch", capability_->serving_operator_.GetCountry());
804 EXPECT_EQ(kOperatorName, cellular_->service()->serving_operator().GetName());
805
806 static const char kTestOperator[] = "Testcom";
807 capability_->serving_operator_.SetName(kTestOperator);
808 capability_->serving_operator_.SetCountry("");
809 capability_->UpdateOperatorInfo();
810 EXPECT_EQ(kTestOperator, capability_->serving_operator_.GetName());
811 EXPECT_EQ("ch", capability_->serving_operator_.GetCountry());
812 EXPECT_EQ(kTestOperator, cellular_->service()->serving_operator().GetName());
813}
814
815TEST_F(CellularCapabilityUniversalTest, CreateFriendlyServiceName) {
816 CellularCapabilityUniversal::friendly_service_name_id_ = 0;
817 EXPECT_EQ("GSMNetwork0", capability_->CreateFriendlyServiceName());
818 EXPECT_EQ("GSMNetwork1", capability_->CreateFriendlyServiceName());
819
820 capability_->serving_operator_.SetCode("1234");
821 EXPECT_EQ("cellular_1234", capability_->CreateFriendlyServiceName());
822
823 static const char kHomeProvider[] = "The GSM Home Provider";
824 cellular_->home_provider_.SetName(kHomeProvider);
825 EXPECT_EQ("cellular_1234", capability_->CreateFriendlyServiceName());
826 capability_->registration_state_ = MM_MODEM_3GPP_REGISTRATION_STATE_HOME;
827 EXPECT_EQ(kHomeProvider, capability_->CreateFriendlyServiceName());
828
829 static const char kTestOperator[] = "A GSM Operator";
830 capability_->serving_operator_.SetName(kTestOperator);
831 EXPECT_EQ(kTestOperator, capability_->CreateFriendlyServiceName());
832
833 capability_->registration_state_ = MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING;
834 EXPECT_EQ(StringPrintf("%s | %s", kHomeProvider, kTestOperator),
835 capability_->CreateFriendlyServiceName());
836}
837
Jason Glasgowef965562012-04-10 16:12:35 -0400838} // namespace shill