blob: 191f54ddcbe87575fd4efbcf5ca21e7a1ba2fc12 [file] [log] [blame]
Arman Ugurayf4c61812013-01-10 18:58:39 -08001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Chris Masoneb925cc82011-06-22 15:39:57 -07002// 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.h"
6
Darin Petkov0828f5f2011-08-11 10:18:52 -07007#include <sys/socket.h>
8#include <linux/if.h>
9#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
10
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include <base/bind.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070012#include <chromeos/dbus/service_constants.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070013
Ben Chan539ab022014-02-03 16:34:57 -080014#include "shill/cellular_bearer.h"
Darin Petkovae0c64e2011-11-15 15:50:27 +010015#include "shill/cellular_capability_cdma.h"
Jason Glasgow82f9ab32012-04-04 14:27:19 -040016#include "shill/cellular_capability_classic.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010017#include "shill/cellular_capability_gsm.h"
Ben Chan09fa2a02012-11-07 22:09:09 -080018#include "shill/cellular_capability_universal.h"
Darin Petkovd9661952011-08-03 16:25:42 -070019#include "shill/cellular_service.h"
Darin Petkov4d6d9412011-08-24 13:19:54 -070020#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070021#include "shill/event_dispatcher.h"
mukesh agrawal28185512013-10-18 16:57:09 -070022#include "shill/mock_adaptors.h"
Thieu Le37b90032012-05-15 15:18:41 -070023#include "shill/mock_cellular_service.h"
mukesh agrawal28185512013-10-18 16:57:09 -070024#include "shill/mock_dbus_properties_proxy.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070025#include "shill/mock_device_info.h"
Darin Petkov77cb6812011-08-15 16:19:41 -070026#include "shill/mock_dhcp_config.h"
27#include "shill/mock_dhcp_provider.h"
mukesh agrawalfbc40d22013-06-28 00:25:13 -070028#include "shill/mock_external_task.h"
mukesh agrawal28185512013-10-18 16:57:09 -070029#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
30#include "shill/mock_mm1_modem_proxy.h"
mukesh agrawalf407d592013-07-31 11:37:57 -070031#include "shill/mock_mm1_modem_simple_proxy.h"
Darin Petkovbec79a22011-08-01 14:47:17 -070032#include "shill/mock_modem_cdma_proxy.h"
Darin Petkov975b5e72011-08-30 11:48:08 -070033#include "shill/mock_modem_gsm_card_proxy.h"
Darin Petkova1e0a1c2011-08-25 15:08:33 -070034#include "shill/mock_modem_gsm_network_proxy.h"
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070035#include "shill/mock_modem_info.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070036#include "shill/mock_modem_proxy.h"
Darin Petkove604f702011-07-28 15:51:17 -070037#include "shill/mock_modem_simple_proxy.h"
mukesh agrawal5d851b12013-07-11 14:09:41 -070038#include "shill/mock_ppp_device.h"
mukesh agrawalf407d592013-07-31 11:37:57 -070039#include "shill/mock_ppp_device_factory.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070040#include "shill/mock_rtnl_handler.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070041#include "shill/property_store_unittest.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070042#include "shill/proxy_factory.h"
mukesh agrawalfbc40d22013-06-28 00:25:13 -070043#include "shill/rpc_task.h" // for RpcTaskDelegate
Ben Chanbe277dd2014-02-05 17:26:47 -080044#include "shill/testing.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070045
Ben Chan09fa2a02012-11-07 22:09:09 -080046// mm/mm-modem.h must be included after cellular_capability_universal.h
47// in order to allow MM_MODEM_CDMA_* to be defined properly.
48#include <mm/mm-modem.h>
49
Eric Shienbrood9a245532012-03-07 14:20:39 -050050using base::Bind;
51using base::Unretained;
Darin Petkovc0865312011-09-16 15:31:20 -070052using std::map;
Chris Masoneb925cc82011-06-22 15:39:57 -070053using std::string;
Eric Shienbrood7fce52c2012-04-13 19:11:02 -040054using std::vector;
Darin Petkovbec79a22011-08-01 14:47:17 -070055using testing::_;
Chris Masoneb9c00592011-10-06 13:10:39 -070056using testing::AnyNumber;
mukesh agrawalf407d592013-07-31 11:37:57 -070057using testing::DoAll;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050058using testing::Invoke;
Arman Ugurayf84a4242013-04-09 20:01:07 -070059using testing::Mock;
Darin Petkov0828f5f2011-08-11 10:18:52 -070060using testing::NiceMock;
Darin Petkove604f702011-07-28 15:51:17 -070061using testing::Return;
mukesh agrawal28185512013-10-18 16:57:09 -070062using testing::SaveArg;
Darin Petkovbec79a22011-08-01 14:47:17 -070063using testing::SetArgumentPointee;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050064using testing::Unused;
Chris Masoneb925cc82011-06-22 15:39:57 -070065
66namespace shill {
67
Darin Petkov0828f5f2011-08-11 10:18:52 -070068class CellularPropertyTest : public PropertyStoreTest {
69 public:
70 CellularPropertyTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070071 : modem_info_(control_interface(),
72 dispatcher(),
73 metrics(),
74 manager(),
75 glib()),
76 device_(new Cellular(&modem_info_,
Darin Petkove9d12e02011-07-27 15:09:37 -070077 "usb0",
Chris Masone626719f2011-08-18 16:58:48 -070078 "00:01:02:03:04:05",
Darin Petkove9d12e02011-07-27 15:09:37 -070079 3,
Ben Chan3ecdf822012-08-06 12:29:23 -070080 Cellular::kTypeCDMA,
Darin Petkov0828f5f2011-08-11 10:18:52 -070081 "",
Darin Petkov137884a2011-10-26 18:52:47 +020082 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040083 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070084 ProxyFactory::GetInstance())) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -070085 virtual ~CellularPropertyTest() {}
Darin Petkove9d12e02011-07-27 15:09:37 -070086
Chris Masoneb925cc82011-06-22 15:39:57 -070087 protected:
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070088 MockModemInfo modem_info_;
Darin Petkov0828f5f2011-08-11 10:18:52 -070089 DeviceRefPtr device_;
Chris Masoneb925cc82011-06-22 15:39:57 -070090};
91
Darin Petkov0828f5f2011-08-11 10:18:52 -070092TEST_F(CellularPropertyTest, Contains) {
Ben Chan7ea768e2013-09-20 15:08:40 -070093 EXPECT_TRUE(device_->store().Contains(kNameProperty));
mukesh agrawalde29fa82011-09-16 16:16:36 -070094 EXPECT_FALSE(device_->store().Contains(""));
Chris Masoneb925cc82011-06-22 15:39:57 -070095}
96
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080097TEST_F(CellularPropertyTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -070098 {
99 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700100 ::DBus::Variant allow_roaming;
101 allow_roaming.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800102 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700103 device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700104 kCellularAllowRoamingProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700105 allow_roaming,
Chris Masonea8a2c252011-06-27 22:16:30 -0700106 &error));
107 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700108 // Ensure that attempting to write a R/O property returns InvalidArgs error.
109 {
110 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800111 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700112 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800113 PropertyStoreTest::kStringV,
114 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700115 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700116 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700117 }
118 {
119 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800120 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700121 kCarrierProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800122 PropertyStoreTest::kStringV,
123 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700124 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700125 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700126 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700127}
128
Darin Petkov0828f5f2011-08-11 10:18:52 -0700129class CellularTest : public testing::Test {
130 public:
131 CellularTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700132 : modem_info_(NULL, &dispatcher_, NULL, NULL, NULL),
133 device_info_(modem_info_.control_interface(), &dispatcher_,
134 modem_info_.metrics(), modem_info_.manager()),
135 dhcp_config_(new MockDHCPConfig(modem_info_.control_interface(),
Paul Stewartd408fdf2012-05-07 17:15:57 -0700136 kTestDeviceName)),
Ben Chan3ecdf822012-08-06 12:29:23 -0700137 create_gsm_card_proxy_from_factory_(false),
Ben Chan3ecdf822012-08-06 12:29:23 -0700138 proxy_factory_(this),
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700139 device_(new Cellular(&modem_info_,
Darin Petkov77cb6812011-08-15 16:19:41 -0700140 kTestDeviceName,
Chris Masone626719f2011-08-18 16:58:48 -0700141 kTestDeviceAddress,
Darin Petkov0828f5f2011-08-11 10:18:52 -0700142 3,
143 Cellular::kTypeGSM,
144 kDBusOwner,
Jason Glasgowa585fc32012-06-06 11:04:09 -0400145 kDBusService,
Darin Petkov137884a2011-10-26 18:52:47 +0200146 kDBusPath,
Thieu Lece4483e2013-01-23 15:12:03 -0800147 &proxy_factory_)) {
mukesh agrawal28185512013-10-18 16:57:09 -0700148 PopulateProxies();
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700149 modem_info_.metrics()->RegisterDevice(device_->interface_index(),
150 Technology::kCellular);
Darin Petkov137884a2011-10-26 18:52:47 +0200151 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700152
153 virtual void SetUp() {
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700154 static_cast<Device *>(device_)->rtnl_handler_ = &rtnl_handler_;
Darin Petkov77cb6812011-08-15 16:19:41 -0700155 device_->set_dhcp_provider(&dhcp_provider_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700156 EXPECT_CALL(*modem_info_.mock_manager(), device_info())
157 .WillRepeatedly(Return(&device_info_));
158 EXPECT_CALL(*modem_info_.mock_manager(), DeregisterService(_))
159 .Times(AnyNumber());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700160 }
161
162 virtual void TearDown() {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500163 device_->DestroyIPConfig();
Darin Petkovfb0625e2012-01-16 13:05:56 +0100164 device_->state_ = Cellular::kStateDisabled;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500165 device_->capability_->ReleaseProxies();
Darin Petkov77cb6812011-08-15 16:19:41 -0700166 device_->set_dhcp_provider(NULL);
mukesh agrawal0381f9a2013-07-11 16:41:52 -0700167 // Break cycle between Cellular and CellularService.
168 device_->service_ = NULL;
169 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700170 }
171
mukesh agrawal28185512013-10-18 16:57:09 -0700172 void PopulateProxies() {
173 dbus_properties_proxy_.reset(new MockDBusPropertiesProxy());
174 proxy_.reset(new MockModemProxy());
175 simple_proxy_.reset(new MockModemSimpleProxy());
176 cdma_proxy_.reset(new MockModemCDMAProxy());
177 gsm_card_proxy_.reset(new MockModemGSMCardProxy());
178 gsm_network_proxy_.reset(new MockModemGSMNetworkProxy());
179 mm1_modem_3gpp_proxy_.reset(new mm1::MockModemModem3gppProxy());
180 mm1_proxy_.reset(new mm1::MockModemProxy());
181 mm1_simple_proxy_.reset(new mm1::MockModemSimpleProxy());
182 }
183
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700184 void InitProviderDB() {
185 modem_info_.SetProviderDB(kTestMobileProviderDBPath);
186 }
187
Eric Shienbrood9a245532012-03-07 14:20:39 -0500188 void InvokeEnable(bool enable, Error *error,
189 const ResultCallback &callback, int timeout) {
190 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500191 }
mukesh agrawal28185512013-10-18 16:57:09 -0700192 void InvokeEnableReturningWrongState(
193 bool enable, Error *error, const ResultCallback &callback, int timeout) {
194 callback.Run(Error(Error::kWrongState));
195 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500196 void InvokeGetSignalQuality(Error *error,
197 const SignalQualityCallback &callback,
198 int timeout) {
199 callback.Run(kStrength, Error());
200 }
201 void InvokeGetModemStatus(Error *error,
202 const DBusPropertyMapCallback &callback,
203 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500204 DBusPropertiesMap props;
205 props["carrier"].writer().append_string(kTestCarrier);
206 props["unknown-property"].writer().append_string("irrelevant-value");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500207 callback.Run(props, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500208 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500209 void InvokeGetModemInfo(Error *error, const ModemInfoCallback &callback,
210 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500211 static const char kManufacturer[] = "Company";
212 static const char kModelID[] = "Gobi 2000";
213 static const char kHWRev[] = "A00B1234";
214 ModemHardwareInfo info;
215 info._1 = kManufacturer;
216 info._2 = kModelID;
217 info._3 = kHWRev;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500218 callback.Run(info, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500219 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500220 void InvokeGetRegistrationState1X(Error *error,
221 const RegistrationStateCallback &callback,
222 int timeout) {
223 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
224 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
225 Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500226 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500227 void InvokeGetIMEI(Error *error, const GSMIdentifierCallback &callback,
228 int timeout) {
229 callback.Run(kIMEI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500230 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500231 void InvokeGetIMSI(Error *error, const GSMIdentifierCallback &callback,
232 int timeout) {
233 callback.Run(kIMSI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500234 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500235 void InvokeGetMSISDN(Error *error, const GSMIdentifierCallback &callback,
236 int timeout) {
237 callback.Run(kMSISDN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500238 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500239 void InvokeGetSPN(Error *error, const GSMIdentifierCallback &callback,
240 int timeout) {
Darin Petkova4ca3c32012-08-17 16:05:24 +0200241 callback.Run(kTestCarrierSPN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500242 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500243 void InvokeGetRegistrationInfo(Error *error,
244 const RegistrationInfoCallback &callback,
245 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500246 static const char kNetworkID[] = "22803";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500247 callback.Run(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING,
248 kNetworkID, kTestCarrier, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500249 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500250 void InvokeRegister(const string &network_id,
251 Error *error,
252 const ResultCallback &callback,
253 int timeout) {
254 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500255 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500256 void InvokeGetRegistrationState(Error *error,
257 const RegistrationStateCallback &callback,
258 int timeout) {
259 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
260 MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
261 Error());
262 }
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400263 void InvokeGetRegistrationStateUnregistered(
264 Error *error,
265 const RegistrationStateCallback &callback,
266 int timeout) {
267 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
268 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
269 Error());
Arman Uguray539c4232012-09-11 10:00:22 -0700270 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500271 void InvokeConnect(DBusPropertiesMap props, Error *error,
272 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400273 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500274 callback.Run(Error());
275 }
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400276 void InvokeConnectFail(DBusPropertiesMap props, Error *error,
Thieu Leb5954a22012-05-18 10:37:34 -0700277 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400278 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
279 callback.Run(Error(Error::kNotOnHomeNetwork));
280 }
Thieu Leb5954a22012-05-18 10:37:34 -0700281 void InvokeConnectFailNoService(DBusPropertiesMap props, Error *error,
282 const ResultCallback &callback, int timeout) {
283 device_->service_ = NULL;
284 callback.Run(Error(Error::kNotOnHomeNetwork));
285 }
Thieu Led4974cd2013-05-23 10:39:28 -0700286 void InvokeConnectSuccessNoService(DBusPropertiesMap props, Error *error,
287 const ResultCallback &callback,
288 int timeout) {
289 device_->service_ = NULL;
290 callback.Run(Error());
291 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500292 void InvokeDisconnect(Error *error, const ResultCallback &callback,
293 int timeout) {
294 if (!callback.is_null())
295 callback.Run(Error());
296 }
Arman Uguray539c4232012-09-11 10:00:22 -0700297 void InvokeDisconnectFail(Error *error, const ResultCallback &callback,
298 int timeout) {
299 error->Populate(Error::kOperationFailed);
300 if (!callback.is_null())
301 callback.Run(*error);
302 }
mukesh agrawalf407d592013-07-31 11:37:57 -0700303 void InvokeDisconnectMM1(const ::DBus::Path &bearer, Error *error,
304 const ResultCallback &callback, int timeout) {
305 if (!callback.is_null())
306 callback.Run(Error());
307 }
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800308 void InvokeScanFailed(Error *error, Unused, Unused) {
309 error->Populate(Error::kOperationFailed);
310 }
311 void InvokeScanInitiated(Error *error, Unused, Unused) {
312 error->Populate(Error::kOperationInitiated);
313 }
mukesh agrawal28185512013-10-18 16:57:09 -0700314 void InvokeSetPowerState(const uint32_t &power_state,
315 Error *error,
316 const ResultCallback &callback,
317 int timeout) {
318 callback.Run(Error());
319 }
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400320 void ExpectCdmaStartModem(string network_technology) {
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400321 if (!device_->IsUnderlyingDeviceEnabled())
322 EXPECT_CALL(*proxy_,
323 Enable(true, _, _, CellularCapability::kTimeoutEnable))
324 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400325 EXPECT_CALL(*simple_proxy_,
326 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
327 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
328 EXPECT_CALL(*proxy_,
329 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
330 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Ben Chan7ea768e2013-09-20 15:08:40 -0700331 if (network_technology == kNetworkTechnology1Xrtt)
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400332 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400333 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState1X));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400334 else
335 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400336 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400337 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
338 .Times(2)
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400339 .WillRepeatedly(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400340 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700341 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400342 }
343
mukesh agrawalee10f372013-08-14 14:07:11 -0700344 void ExpectDisconnectCapabilityUniversal() {
345 SetCellularType(Cellular::kTypeUniversal);
346 device_->state_ = Cellular::kStateConnected;
347 EXPECT_CALL(*mm1_simple_proxy_, Disconnect(_, _, _, _))
348 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnectMM1));
349 GetCapabilityUniversal()->modem_simple_proxy_.reset(
350 mm1_simple_proxy_.release());
mukesh agrawalee10f372013-08-14 14:07:11 -0700351 }
352
353 void VerifyDisconnect() {
354 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
355 }
356
mukesh agrawalf407d592013-07-31 11:37:57 -0700357 void StartPPP(int pid) {
358 MockGLib &mock_glib(*dynamic_cast<MockGLib *>(modem_info_.glib()));
359 EXPECT_CALL(mock_glib, ChildWatchAdd(pid, _, _));
360 EXPECT_CALL(mock_glib, SpawnAsync(_, _, _, _, _, _, _, _))
361 .WillOnce(DoAll(SetArgumentPointee<6>(pid), Return(true)));
362 device_->StartPPP("fake_serial_device");
363 EXPECT_FALSE(device_->ipconfig()); // No DHCP client.
364 EXPECT_FALSE(device_->selected_service());
mukesh agrawalfc362912013-08-06 18:10:07 -0700365 EXPECT_FALSE(device_->is_ppp_authenticating_);
mukesh agrawalf407d592013-07-31 11:37:57 -0700366 EXPECT_TRUE(device_->ppp_task_);
367 Mock::VerifyAndClearExpectations(&mock_glib);
368 }
369
mukesh agrawal28185512013-10-18 16:57:09 -0700370 void FakeUpConnectedPPP() {
371 const char kInterfaceName[] = "fake-ppp-device";
372 const int kInterfaceIndex = -1;
373 auto mock_ppp_device = make_scoped_refptr(new MockPPPDevice(
374 modem_info_.control_interface(), NULL, NULL, NULL, kInterfaceName,
375 kInterfaceIndex));
376 device_->ppp_device_ = mock_ppp_device;
377 device_->state_ = Cellular::kStateConnected;
378 }
379
380 void ExpectPPPStopped() {
381 auto mock_ppp_device =
382 dynamic_cast<MockPPPDevice *>(device_->ppp_device_.get());
383 EXPECT_CALL(*mock_ppp_device, DropConnection());
384 }
385
386 void VerifyPPPStopped() {
387 EXPECT_FALSE(device_->ppp_task_);
388 EXPECT_FALSE(device_->ppp_device_);
389 }
390
391 void SetCommonOnAfterResumeExpectations() {
392 EXPECT_CALL(*dbus_properties_proxy_, GetAll(_))
393 .WillRepeatedly(Return(DBusPropertiesMap()));
394 EXPECT_CALL(*mm1_proxy_, set_state_changed_callback(_)).Times(AnyNumber());
395 EXPECT_CALL(*modem_info_.mock_metrics(), NotifyDeviceScanStarted(_))
396 .Times(AnyNumber());
397 EXPECT_CALL(*modem_info_.mock_cellular_operator_info(),
398 GetOLPByMCCMNC(_)).Times(AnyNumber());
399 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies())
400 .Times(AnyNumber());
401 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor()),
402 EmitBoolChanged(_, _)).Times(AnyNumber());
403 }
404
405 mm1::MockModemProxy *SetupOnAfterResume() {
406 SetCellularType(Cellular::kTypeUniversal);
407 SetCommonOnAfterResumeExpectations();
408 return mm1_proxy_.get(); // Before the capability snags it.
409 }
410
Eric Shienbrood9a245532012-03-07 14:20:39 -0500411 MOCK_METHOD1(TestCallback, void(const Error &error));
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500412
Darin Petkov0828f5f2011-08-11 10:18:52 -0700413 protected:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500414 static const char kTestDeviceName[];
415 static const char kTestDeviceAddress[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500416 static const char kDBusOwner[];
Jason Glasgowa585fc32012-06-06 11:04:09 -0400417 static const char kDBusService[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500418 static const char kDBusPath[];
419 static const char kTestCarrier[];
Darin Petkova4ca3c32012-08-17 16:05:24 +0200420 static const char kTestCarrierSPN[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500421 static const char kMEID[];
422 static const char kIMEI[];
423 static const char kIMSI[];
424 static const char kMSISDN[];
425 static const char kTestMobileProviderDBPath[];
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800426 static const Stringmaps kTestNetworksGSM;
427 static const Stringmaps kTestNetworksCellular;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500428 static const int kStrength;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500429
Darin Petkov0828f5f2011-08-11 10:18:52 -0700430 class TestProxyFactory : public ProxyFactory {
431 public:
Paul Stewart7355ce12011-09-02 10:47:01 -0700432 explicit TestProxyFactory(CellularTest *test) : test_(test) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -0700433
mukesh agrawal28185512013-10-18 16:57:09 -0700434 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
435 const std::string &path,
436 const std::string &service) {
437 return test_->dbus_properties_proxy_.release();
438 }
439
mukesh agrawal1830fa12011-09-26 14:31:40 -0700440 virtual ModemProxyInterface *CreateModemProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700441 const string &/*path*/,
442 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700443 return test_->proxy_.release();
444 }
445
446 virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700447 const string &/*path*/,
448 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700449 return test_->simple_proxy_.release();
450 }
451
452 virtual ModemCDMAProxyInterface *CreateModemCDMAProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700453 const string &/*path*/,
454 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700455 return test_->cdma_proxy_.release();
456 }
457
Darin Petkov975b5e72011-08-30 11:48:08 -0700458 virtual ModemGSMCardProxyInterface *CreateModemGSMCardProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700459 const string &/*path*/,
460 const string &/*service*/) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700461 // TODO(benchan): This code conditionally returns a NULL pointer to avoid
462 // CellularCapabilityGSM::InitProperties (and thus
463 // CellularCapabilityGSM::GetIMSI) from being called during the
464 // construction. Remove this workaround after refactoring the tests.
465 return test_->create_gsm_card_proxy_from_factory_ ?
466 test_->gsm_card_proxy_.release() : NULL;
Darin Petkov975b5e72011-08-30 11:48:08 -0700467 }
468
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700469 virtual ModemGSMNetworkProxyInterface *CreateModemGSMNetworkProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700470 const string &/*path*/,
471 const string &/*service*/) {
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700472 return test_->gsm_network_proxy_.release();
473 }
474
mukesh agrawal28185512013-10-18 16:57:09 -0700475 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
476 const std::string &path,
477 const std::string &service) {
478 return test_->mm1_modem_3gpp_proxy_.release();
479 }
480
481 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
482 const std::string &path,
483 const std::string &service) {
484 return test_->mm1_proxy_.release();
485 }
486
487 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
488 const string &/*path*/,
489 const string &/*service*/) {
490 return test_->mm1_simple_proxy_.release();
491 }
492
Darin Petkov0828f5f2011-08-11 10:18:52 -0700493 private:
494 CellularTest *test_;
495 };
Darin Petkov0828f5f2011-08-11 10:18:52 -0700496 void StartRTNLHandler();
497 void StopRTNLHandler();
498
Ben Chan3ecdf822012-08-06 12:29:23 -0700499 void AllowCreateGSMCardProxyFromFactory() {
500 create_gsm_card_proxy_from_factory_ = true;
501 }
502
Darin Petkov721ac932011-11-16 15:43:09 +0100503 void SetCellularType(Cellular::Type type) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700504 device_->InitCapability(type);
Darin Petkov721ac932011-11-16 15:43:09 +0100505 }
506
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400507 CellularCapabilityClassic *GetCapabilityClassic() {
508 return dynamic_cast<CellularCapabilityClassic *>(
509 device_->capability_.get());
510 }
511
Darin Petkovae0c64e2011-11-15 15:50:27 +0100512 CellularCapabilityCDMA *GetCapabilityCDMA() {
513 return dynamic_cast<CellularCapabilityCDMA *>(device_->capability_.get());
514 }
515
516 CellularCapabilityGSM *GetCapabilityGSM() {
517 return dynamic_cast<CellularCapabilityGSM *>(device_->capability_.get());
518 }
519
Ben Chan09fa2a02012-11-07 22:09:09 -0800520 CellularCapabilityUniversal *GetCapabilityUniversal() {
521 return dynamic_cast<CellularCapabilityUniversal *>(
522 device_->capability_.get());
523 }
524
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700525 // Different tests simulate a cellular service being set using a real /mock
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700526 // service.
Arman Ugurayf84a4242013-04-09 20:01:07 -0700527 CellularService *SetService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700528 device_->service_ = new CellularService(&modem_info_, device_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700529 return device_->service_;
530 }
Arman Ugurayf84a4242013-04-09 20:01:07 -0700531 MockCellularService *SetMockService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700532 device_->service_ = new MockCellularService(&modem_info_, device_);
533 return static_cast<MockCellularService *>(device_->service_.get());
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700534 }
535
mukesh agrawal28185512013-10-18 16:57:09 -0700536 void set_enabled_persistent(bool new_value) {
537 device_->enabled_persistent_ = new_value;
538 }
539
Ben Chan539ab022014-02-03 16:34:57 -0800540 void SetCapabilityUniversalActiveBearer(scoped_ptr<CellularBearer> bearer) {
541 SetCellularType(Cellular::kTypeUniversal);
542 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
543 capability->active_bearer_ = bearer.Pass();
544 }
545
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700546 EventDispatcher dispatcher_;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700547 MockModemInfo modem_info_;
Chris Masone2ae797d2011-08-23 20:41:00 -0700548 MockDeviceInfo device_info_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700549 NiceMock<MockRTNLHandler> rtnl_handler_;
550
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500551 MockDHCPProvider dhcp_provider_;
552 scoped_refptr<MockDHCPConfig> dhcp_config_;
553
Ben Chan3ecdf822012-08-06 12:29:23 -0700554 bool create_gsm_card_proxy_from_factory_;
mukesh agrawal28185512013-10-18 16:57:09 -0700555 scoped_ptr<MockDBusPropertiesProxy> dbus_properties_proxy_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700556 scoped_ptr<MockModemProxy> proxy_;
557 scoped_ptr<MockModemSimpleProxy> simple_proxy_;
558 scoped_ptr<MockModemCDMAProxy> cdma_proxy_;
Darin Petkov975b5e72011-08-30 11:48:08 -0700559 scoped_ptr<MockModemGSMCardProxy> gsm_card_proxy_;
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700560 scoped_ptr<MockModemGSMNetworkProxy> gsm_network_proxy_;
mukesh agrawal28185512013-10-18 16:57:09 -0700561 scoped_ptr<mm1::MockModemModem3gppProxy> mm1_modem_3gpp_proxy_;
562 scoped_ptr<mm1::MockModemProxy> mm1_proxy_;
mukesh agrawalf407d592013-07-31 11:37:57 -0700563 scoped_ptr<mm1::MockModemSimpleProxy> mm1_simple_proxy_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700564 TestProxyFactory proxy_factory_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700565 CellularRefPtr device_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700566};
567
Darin Petkov77cb6812011-08-15 16:19:41 -0700568const char CellularTest::kTestDeviceName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700569const char CellularTest::kTestDeviceAddress[] = "00:01:02:03:04:05";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700570const char CellularTest::kDBusOwner[] = ":1.19";
Jason Glasgowa585fc32012-06-06 11:04:09 -0400571const char CellularTest::kDBusService[] = "org.chromium.ModemManager";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700572const char CellularTest::kDBusPath[] = "/org/chromium/ModemManager/Gobi/0";
Darin Petkov51489002011-08-18 13:13:20 -0700573const char CellularTest::kTestCarrier[] = "The Cellular Carrier";
Darin Petkova4ca3c32012-08-17 16:05:24 +0200574const char CellularTest::kTestCarrierSPN[] = "Home Provider";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500575const char CellularTest::kMEID[] = "01234567EF8901";
Darin Petkov975b5e72011-08-30 11:48:08 -0700576const char CellularTest::kIMEI[] = "987654321098765";
577const char CellularTest::kIMSI[] = "123456789012345";
578const char CellularTest::kMSISDN[] = "12345678901";
Darin Petkov137884a2011-10-26 18:52:47 +0200579const char CellularTest::kTestMobileProviderDBPath[] =
580 "provider_db_unittest.bfd";
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800581const Stringmaps CellularTest::kTestNetworksGSM =
582 {{{CellularCapabilityGSM::kNetworkPropertyStatus, "1"},
583 {CellularCapabilityGSM::kNetworkPropertyID, "0000"},
584 {CellularCapabilityGSM::kNetworkPropertyLongName, "some_long_name"},
585 {CellularCapabilityGSM::kNetworkPropertyShortName, "short"}}};
586const Stringmaps CellularTest::kTestNetworksCellular =
587 {{{kStatusProperty, "available"},
588 {kNetworkIdProperty, "0000"},
589 {kLongNameProperty, "some_long_name"},
590 {kShortNameProperty, "short"}}};
Eric Shienbrood9a245532012-03-07 14:20:39 -0500591const int CellularTest::kStrength = 90;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700592
Darin Petkove9d12e02011-07-27 15:09:37 -0700593TEST_F(CellularTest, GetStateString) {
Darin Petkovcc044422011-08-17 13:30:06 -0700594 EXPECT_EQ("CellularStateDisabled",
Ben Chanf45b3232013-10-08 20:54:01 -0700595 Cellular::GetStateString(Cellular::kStateDisabled));
Darin Petkovcc044422011-08-17 13:30:06 -0700596 EXPECT_EQ("CellularStateEnabled",
Ben Chanf45b3232013-10-08 20:54:01 -0700597 Cellular::GetStateString(Cellular::kStateEnabled));
Darin Petkovcc044422011-08-17 13:30:06 -0700598 EXPECT_EQ("CellularStateRegistered",
Ben Chanf45b3232013-10-08 20:54:01 -0700599 Cellular::GetStateString(Cellular::kStateRegistered));
Darin Petkovcc044422011-08-17 13:30:06 -0700600 EXPECT_EQ("CellularStateConnected",
Ben Chanf45b3232013-10-08 20:54:01 -0700601 Cellular::GetStateString(Cellular::kStateConnected));
Darin Petkovcc044422011-08-17 13:30:06 -0700602 EXPECT_EQ("CellularStateLinked",
Ben Chanf45b3232013-10-08 20:54:01 -0700603 Cellular::GetStateString(Cellular::kStateLinked));
604}
605
606TEST_F(CellularTest, GetModemStateString) {
Ben Chan7b7d63d2013-10-18 14:53:05 -0700607 EXPECT_EQ("CellularModemStateFailed",
608 Cellular::GetModemStateString(Cellular::kModemStateFailed));
Ben Chanf45b3232013-10-08 20:54:01 -0700609 EXPECT_EQ("CellularModemStateUnknown",
610 Cellular::GetModemStateString(Cellular::kModemStateUnknown));
611 EXPECT_EQ("CellularModemStateInitializing",
612 Cellular::GetModemStateString(Cellular::kModemStateInitializing));
613 EXPECT_EQ("CellularModemStateLocked",
614 Cellular::GetModemStateString(Cellular::kModemStateLocked));
615 EXPECT_EQ("CellularModemStateDisabled",
616 Cellular::GetModemStateString(Cellular::kModemStateDisabled));
617 EXPECT_EQ("CellularModemStateDisabling",
618 Cellular::GetModemStateString(Cellular::kModemStateDisabling));
619 EXPECT_EQ("CellularModemStateEnabling",
620 Cellular::GetModemStateString(Cellular::kModemStateEnabling));
621 EXPECT_EQ("CellularModemStateEnabled",
622 Cellular::GetModemStateString(Cellular::kModemStateEnabled));
623 EXPECT_EQ("CellularModemStateSearching",
624 Cellular::GetModemStateString(Cellular::kModemStateSearching));
625 EXPECT_EQ("CellularModemStateRegistered",
626 Cellular::GetModemStateString(Cellular::kModemStateRegistered));
627 EXPECT_EQ("CellularModemStateDisconnecting",
628 Cellular::GetModemStateString(Cellular::kModemStateDisconnecting));
629 EXPECT_EQ("CellularModemStateConnecting",
630 Cellular::GetModemStateString(Cellular::kModemStateConnecting));
631 EXPECT_EQ("CellularModemStateConnected",
632 Cellular::GetModemStateString(Cellular::kModemStateConnected));
Darin Petkove9d12e02011-07-27 15:09:37 -0700633}
634
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700635TEST_F(CellularTest, StartCDMARegister) {
Darin Petkov721ac932011-11-16 15:43:09 +0100636 SetCellularType(Cellular::kTypeCDMA);
Ben Chan7ea768e2013-09-20 15:08:40 -0700637 ExpectCdmaStartModem(kNetworkTechnology1Xrtt);
Darin Petkov975b5e72011-08-30 11:48:08 -0700638 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500639 Error error;
640 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
Darin Petkov0828f5f2011-08-11 10:18:52 -0700641 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800642 EXPECT_EQ(kMEID, device_->meid());
643 EXPECT_EQ(kTestCarrier, device_->carrier());
Darin Petkovbac96002011-08-09 13:22:00 -0700644 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovd2045802011-08-23 11:09:25 -0700645 ASSERT_TRUE(device_->service_.get());
Ben Chan7ea768e2013-09-20 15:08:40 -0700646 EXPECT_EQ(kNetworkTechnology1Xrtt, device_->service_->network_technology());
Darin Petkov22b72bf2011-08-29 14:01:20 -0700647 EXPECT_EQ(kStrength, device_->service_->strength());
Ben Chan7ea768e2013-09-20 15:08:40 -0700648 EXPECT_EQ(kRoamingStateHome, device_->service_->roaming_state());
Darin Petkovbac96002011-08-09 13:22:00 -0700649}
650
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700651TEST_F(CellularTest, StartGSMRegister) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700652 InitProviderDB();
Eric Shienbrood9a245532012-03-07 14:20:39 -0500653 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500654 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500655 EXPECT_CALL(*gsm_card_proxy_,
656 GetIMEI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500657 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMEI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500658 EXPECT_CALL(*gsm_card_proxy_,
659 GetIMSI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500660 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMSI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500661 EXPECT_CALL(*gsm_card_proxy_,
662 GetSPN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500663 .WillOnce(Invoke(this, &CellularTest::InvokeGetSPN));
664 EXPECT_CALL(*gsm_card_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500665 GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500666 .WillOnce(Invoke(this, &CellularTest::InvokeGetMSISDN));
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700667 EXPECT_CALL(*gsm_network_proxy_, AccessTechnology())
668 .WillOnce(Return(MM_MODEM_GSM_ACCESS_TECH_EDGE));
Darin Petkov63138a92012-02-06 14:09:15 +0100669 EXPECT_CALL(*gsm_card_proxy_, EnabledFacilityLocks())
670 .WillOnce(Return(MM_MODEM_GSM_FACILITY_SIM));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500671 EXPECT_CALL(*proxy_, GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500672 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Darin Petkov137884a2011-10-26 18:52:47 +0200673 static const char kNetworkID[] = "22803";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500674 EXPECT_CALL(*gsm_network_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500675 GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500676 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationInfo));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500677 EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality(NULL, _, _))
678 .Times(2)
679 .WillRepeatedly(Invoke(this,
680 &CellularTest::InvokeGetSignalQuality));
681 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700682 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Ben Chan3ecdf822012-08-06 12:29:23 -0700683 AllowCreateGSMCardProxyFromFactory();
684
Eric Shienbrood9a245532012-03-07 14:20:39 -0500685 Error error;
686 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
687 EXPECT_TRUE(error.IsSuccess());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700688 dispatcher_.DispatchPendingEvents();
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800689 EXPECT_EQ(kIMEI, device_->imei());
690 EXPECT_EQ(kIMSI, device_->imsi());
Darin Petkova4ca3c32012-08-17 16:05:24 +0200691 EXPECT_EQ(kTestCarrierSPN, GetCapabilityGSM()->spn_);
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800692 EXPECT_EQ(kMSISDN, device_->mdn());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700693 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
694 ASSERT_TRUE(device_->service_.get());
Ben Chan7ea768e2013-09-20 15:08:40 -0700695 EXPECT_EQ(kNetworkTechnologyEdge, device_->service_->network_technology());
Darin Petkov63138a92012-02-06 14:09:15 +0100696 EXPECT_TRUE(GetCapabilityGSM()->sim_lock_status_.enabled);
Darin Petkov22b72bf2011-08-29 14:01:20 -0700697 EXPECT_EQ(kStrength, device_->service_->strength());
Ben Chan7ea768e2013-09-20 15:08:40 -0700698 EXPECT_EQ(kRoamingStateRoaming, device_->service_->roaming_state());
Darin Petkov137884a2011-10-26 18:52:47 +0200699 EXPECT_EQ(kNetworkID, device_->service_->serving_operator().GetCode());
Darin Petkova4ca3c32012-08-17 16:05:24 +0200700 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Darin Petkov137884a2011-10-26 18:52:47 +0200701 EXPECT_EQ("ch", device_->service_->serving_operator().GetCountry());
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700702}
703
Darin Petkovbac96002011-08-09 13:22:00 -0700704TEST_F(CellularTest, StartConnected) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700705 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
706 .WillOnce(Return(true));
Darin Petkov721ac932011-11-16 15:43:09 +0100707 SetCellularType(Cellular::kTypeCDMA);
Darin Petkovbac96002011-08-09 13:22:00 -0700708 device_->set_modem_state(Cellular::kModemStateConnected);
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800709 device_->set_meid(kMEID);
Ben Chan7ea768e2013-09-20 15:08:40 -0700710 ExpectCdmaStartModem(kNetworkTechnologyEvdo);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500711 Error error;
712 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
713 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700714 dispatcher_.DispatchPendingEvents();
Darin Petkovbac96002011-08-09 13:22:00 -0700715 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
716}
717
Darin Petkov0828f5f2011-08-11 10:18:52 -0700718TEST_F(CellularTest, StartLinked) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700719 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
720 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
Darin Petkov721ac932011-11-16 15:43:09 +0100721 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700722 device_->set_modem_state(Cellular::kModemStateConnected);
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800723 device_->set_meid(kMEID);
Ben Chan7ea768e2013-09-20 15:08:40 -0700724 ExpectCdmaStartModem(kNetworkTechnologyEvdo);
Paul Stewart75a68b92013-10-24 10:50:27 -0700725 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _, _))
Darin Petkov77cb6812011-08-15 16:19:41 -0700726 .WillOnce(Return(dhcp_config_));
727 EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700728 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_)).Times(3);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500729 Error error;
730 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
731 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700732 dispatcher_.DispatchPendingEvents();
733 EXPECT_EQ(Cellular::kStateLinked, device_->state_);
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700734 EXPECT_EQ(Service::kStateConfiguring, device_->service_->state());
735 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700736}
737
Darin Petkov3335b372011-08-22 11:05:32 -0700738TEST_F(CellularTest, CreateService) {
Darin Petkov721ac932011-11-16 15:43:09 +0100739 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov3335b372011-08-22 11:05:32 -0700740 static const char kPaymentURL[] = "https://payment.url";
741 static const char kUsageURL[] = "https://usage.url";
Darin Petkov3335b372011-08-22 11:05:32 -0700742 device_->home_provider_.SetName(kTestCarrier);
Darin Petkov381928f2012-02-02 23:00:12 +0100743 GetCapabilityCDMA()->olp_.SetURL(kPaymentURL);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100744 GetCapabilityCDMA()->usage_url_ = kUsageURL;
Darin Petkov3335b372011-08-22 11:05:32 -0700745 device_->CreateService();
746 ASSERT_TRUE(device_->service_.get());
Darin Petkov381928f2012-02-02 23:00:12 +0100747 EXPECT_EQ(kPaymentURL, device_->service_->olp().GetURL());
Darin Petkov3335b372011-08-22 11:05:32 -0700748 EXPECT_EQ(kUsageURL, device_->service_->usage_url());
749 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800750 ASSERT_FALSE(device_->service_->activate_over_non_cellular_network());
Darin Petkov3335b372011-08-22 11:05:32 -0700751}
752
Darin Petkovc5f56562011-08-06 16:40:05 -0700753namespace {
754
755MATCHER(ContainsPhoneNumber, "") {
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400756 return ContainsKey(arg,
757 CellularCapabilityClassic::kConnectPropertyPhoneNumber);
Darin Petkovc5f56562011-08-06 16:40:05 -0700758}
759
Eric Shienbrood9a245532012-03-07 14:20:39 -0500760} // namespace
Darin Petkovc5f56562011-08-06 16:40:05 -0700761
762TEST_F(CellularTest, Connect) {
Darin Petkov4d6d9412011-08-24 13:19:54 -0700763 Error error;
Chris Masone2ae797d2011-08-23 20:41:00 -0700764 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700765 .Times(2)
766 .WillRepeatedly(Return(true));
Darin Petkovc5f56562011-08-06 16:40:05 -0700767 device_->state_ = Cellular::kStateConnected;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700768 device_->Connect(&error);
769 EXPECT_EQ(Error::kAlreadyConnected, error.type());
770 error.Populate(Error::kSuccess);
Darin Petkovc5f56562011-08-06 16:40:05 -0700771
Darin Petkov0828f5f2011-08-11 10:18:52 -0700772 device_->state_ = Cellular::kStateLinked;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700773 device_->Connect(&error);
774 EXPECT_EQ(Error::kAlreadyConnected, error.type());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700775
Thieu Lec7d8cd12013-02-13 11:38:14 -0800776 device_->state_ = Cellular::kStateEnabled;
777 device_->Connect(&error);
778 EXPECT_EQ(Error::kNotRegistered, error.type());
779
780 error.Reset();
781 device_->state_ = Cellular::kStateDisabled;
782 device_->Connect(&error);
783 EXPECT_EQ(Error::kNotRegistered, error.type());
784
Darin Petkovc5f56562011-08-06 16:40:05 -0700785 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700786 SetService();
Darin Petkovd2045802011-08-23 11:09:25 -0700787
Jason Glasgow7b461df2012-05-01 16:38:45 -0400788 device_->allow_roaming_ = false;
Ben Chan7ea768e2013-09-20 15:08:40 -0700789 device_->service_->roaming_state_ = kRoamingStateRoaming;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700790 device_->Connect(&error);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700791 EXPECT_EQ(Error::kNotOnHomeNetwork, error.type());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500792
Darin Petkov4d6d9412011-08-24 13:19:54 -0700793 error.Populate(Error::kSuccess);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500794 EXPECT_CALL(*simple_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500795 Connect(ContainsPhoneNumber(), _, _,
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500796 CellularCapability::kTimeoutConnect))
797 .Times(2)
798 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400799 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Ben Chan7ea768e2013-09-20 15:08:40 -0700800 device_->service_->roaming_state_ = kRoamingStateHome;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500801 device_->state_ = Cellular::kStateRegistered;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700802 device_->Connect(&error);
803 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc5f56562011-08-06 16:40:05 -0700804 dispatcher_.DispatchPendingEvents();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500805 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
806
Jason Glasgow7b461df2012-05-01 16:38:45 -0400807 device_->allow_roaming_ = true;
Ben Chan7ea768e2013-09-20 15:08:40 -0700808 device_->service_->roaming_state_ = kRoamingStateRoaming;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500809 device_->state_ = Cellular::kStateRegistered;
810 device_->Connect(&error);
811 EXPECT_TRUE(error.IsSuccess());
812 dispatcher_.DispatchPendingEvents();
813 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
Darin Petkovc5f56562011-08-06 16:40:05 -0700814}
815
Eric Shienbrood9a245532012-03-07 14:20:39 -0500816TEST_F(CellularTest, Disconnect) {
817 Error error;
818 device_->state_ = Cellular::kStateRegistered;
819 device_->Disconnect(&error);
820 EXPECT_EQ(Error::kNotConnected, error.type());
821 error.Reset();
822
Darin Petkovfb0625e2012-01-16 13:05:56 +0100823 device_->state_ = Cellular::kStateConnected;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500824 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800825 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood9a245532012-03-07 14:20:39 -0500826 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400827 GetCapabilityClassic()->proxy_.reset(proxy_.release());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500828 device_->Disconnect(&error);
829 EXPECT_TRUE(error.IsSuccess());
830 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100831}
832
Arman Uguray539c4232012-09-11 10:00:22 -0700833TEST_F(CellularTest, DisconnectFailure) {
834 // Test the case where the underlying modem state is set
835 // to disconnecting, but shill thinks it's still connected
836 Error error;
837 device_->state_ = Cellular::kStateConnected;
838 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800839 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Arman Uguray539c4232012-09-11 10:00:22 -0700840 .Times(2)
841 .WillRepeatedly(Invoke(this, &CellularTest::InvokeDisconnectFail));
842 GetCapabilityClassic()->proxy_.reset(proxy_.release());
843 device_->modem_state_ = Cellular::kModemStateDisconnecting;
844 device_->Disconnect(&error);
845 EXPECT_TRUE(error.IsFailure());
846 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
847
848 device_->modem_state_ = Cellular::kModemStateConnected;
849 device_->Disconnect(&error);
850 EXPECT_TRUE(error.IsFailure());
851 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
852}
853
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400854TEST_F(CellularTest, ConnectFailure) {
855 SetCellularType(Cellular::kTypeCDMA);
856 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700857 SetService();
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400858 ASSERT_EQ(Service::kStateIdle, device_->service_->state());
859 EXPECT_CALL(*simple_proxy_,
860 Connect(_, _, _, CellularCapability::kTimeoutConnect))
861 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFail));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400862 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400863 Error error;
864 device_->Connect(&error);
865 EXPECT_EQ(Service::kStateFailure, device_->service_->state());
866}
867
Thieu Leb5954a22012-05-18 10:37:34 -0700868TEST_F(CellularTest, ConnectFailureNoService) {
869 // Make sure we don't crash if the connect failed and there is no
870 // CellularService object. This can happen if the modem is enabled and
871 // then quick disabled.
872 SetCellularType(Cellular::kTypeCDMA);
873 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700874 SetService();
Thieu Leb5954a22012-05-18 10:37:34 -0700875 EXPECT_CALL(
876 *simple_proxy_,
877 Connect(_, _, _, CellularCapability::kTimeoutConnect))
878 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFailNoService));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700879 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_));
Thieu Leb5954a22012-05-18 10:37:34 -0700880 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
881 Error error;
882 device_->Connect(&error);
883}
884
Thieu Led4974cd2013-05-23 10:39:28 -0700885TEST_F(CellularTest, ConnectSuccessNoService) {
886 // Make sure we don't crash if the connect succeeds but the service was
887 // destroyed before the connect request completes.
888 SetCellularType(Cellular::kTypeCDMA);
889 device_->state_ = Cellular::kStateRegistered;
890 SetService();
891 EXPECT_CALL(
892 *simple_proxy_,
893 Connect(_, _, _, CellularCapability::kTimeoutConnect))
894 .WillOnce(Invoke(this, &CellularTest::InvokeConnectSuccessNoService));
895 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_));
896 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
897 Error error;
898 device_->Connect(&error);
899}
900
Arman Uguray32c76402012-11-27 14:01:13 -0800901TEST_F(CellularTest, LinkEventWontDestroyService) {
902 // If the network interface goes down, Cellular::LinkEvent should
903 // drop the connection but the service object should persist.
904 device_->state_ = Cellular::kStateLinked;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700905 CellularService *service = SetService();
Arman Uguray32c76402012-11-27 14:01:13 -0800906 device_->LinkEvent(0, 0); // flags doesn't contain IFF_UP
907 EXPECT_EQ(device_->state_, Cellular::kStateConnected);
908 EXPECT_EQ(device_->service_, service);
909}
910
Arman Ugurayed8e6102012-11-29 14:47:20 -0800911TEST_F(CellularTest, UseNoArpGateway) {
Paul Stewart75a68b92013-10-24 10:50:27 -0700912 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, false, false))
Arman Ugurayed8e6102012-11-29 14:47:20 -0800913 .WillOnce(Return(dhcp_config_));
914 device_->AcquireIPConfig();
915}
916
Ben Chan09fa2a02012-11-07 22:09:09 -0800917TEST_F(CellularTest, HandleNewRegistrationStateForServiceRequiringActivation) {
918 SetCellularType(Cellular::kTypeUniversal);
919
920 // Service activation is needed
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800921 device_->set_mdn("0000000000");
Arman Ugurayf4c61812013-01-10 18:58:39 -0800922 CellularService::OLP olp;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700923 EXPECT_CALL(*modem_info_.mock_cellular_operator_info(), GetOLPByMCCMNC(_))
Arman Ugurayf4c61812013-01-10 18:58:39 -0800924 .WillRepeatedly(Return(&olp));
Arman Uguray41cc6342013-03-29 16:34:39 -0700925 EXPECT_CALL(*modem_info_.mock_pending_activation_store(),
926 GetActivationState(_,_))
927 .WillRepeatedly(Return(PendingActivationStore::kStateUnknown));
Ben Chan09fa2a02012-11-07 22:09:09 -0800928
929 device_->state_ = Cellular::kStateDisabled;
930 device_->HandleNewRegistrationState();
931 EXPECT_FALSE(device_->service_.get());
932
933 device_->state_ = Cellular::kStateEnabled;
934 device_->HandleNewRegistrationState();
935 EXPECT_TRUE(device_->service_.get());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800936 EXPECT_TRUE(device_->service_->activate_over_non_cellular_network());
Ben Chan09fa2a02012-11-07 22:09:09 -0800937}
938
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400939TEST_F(CellularTest, ModemStateChangeEnable) {
940 EXPECT_CALL(*simple_proxy_,
941 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
942 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
943 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
944 EXPECT_CALL(*proxy_,
945 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
946 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
947 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
948 .WillOnce(Invoke(this,
949 &CellularTest::InvokeGetRegistrationStateUnregistered));
950 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
951 .WillOnce(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700952 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400953 device_->state_ = Cellular::kStateDisabled;
954 device_->set_modem_state(Cellular::kModemStateDisabled);
955 SetCellularType(Cellular::kTypeCDMA);
956
957 DBusPropertiesMap props;
958 props[CellularCapabilityClassic::kModemPropertyEnabled].writer().
959 append_bool(true);
960 device_->OnDBusPropertiesChanged(MM_MODEM_INTERFACE, props, vector<string>());
961 dispatcher_.DispatchPendingEvents();
962
963 EXPECT_EQ(Cellular::kModemStateEnabled, device_->modem_state());
964 EXPECT_EQ(Cellular::kStateEnabled, device_->state());
965 EXPECT_TRUE(device_->enabled());
966}
967
968TEST_F(CellularTest, ModemStateChangeDisable) {
969 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800970 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400971 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
972 EXPECT_CALL(*proxy_,
Thieu Lec8d2d962012-05-15 14:31:18 -0700973 Enable(false, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400974 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700975 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400976 device_->enabled_ = true;
977 device_->enabled_pending_ = true;
978 device_->state_ = Cellular::kStateEnabled;
979 device_->set_modem_state(Cellular::kModemStateEnabled);
980 SetCellularType(Cellular::kTypeCDMA);
981 GetCapabilityClassic()->InitProxies();
982
983 GetCapabilityClassic()->OnModemStateChangedSignal(kModemClassicStateEnabled,
984 kModemClassicStateDisabled,
985 0);
986 dispatcher_.DispatchPendingEvents();
987
988 EXPECT_EQ(Cellular::kModemStateDisabled, device_->modem_state());
989 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
990 EXPECT_FALSE(device_->enabled());
991}
992
Thieu Led0012052012-07-25 16:09:09 -0700993TEST_F(CellularTest, ModemStateChangeStaleConnected) {
994 // Test to make sure that we ignore stale modem Connected state transitions.
995 // When a modem is asked to connect and before the connect completes, the
996 // modem is disabled, it may send a stale Connected state transition after
997 // it has been disabled.
998 device_->state_ = Cellular::kStateDisabled;
Arman Uguray1ee93912013-09-24 21:24:10 -0700999 device_->modem_state_ = Cellular::kModemStateEnabling;
1000 device_->OnModemStateChanged(Cellular::kModemStateConnected);
Thieu Led0012052012-07-25 16:09:09 -07001001 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
1002}
1003
1004TEST_F(CellularTest, ModemStateChangeValidConnected) {
1005 device_->state_ = Cellular::kStateEnabled;
Arman Uguray1ee93912013-09-24 21:24:10 -07001006 device_->modem_state_ = Cellular::kModemStateConnecting;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -07001007 SetService();
Arman Uguray1ee93912013-09-24 21:24:10 -07001008 device_->OnModemStateChanged(Cellular::kModemStateConnected);
Thieu Led0012052012-07-25 16:09:09 -07001009 EXPECT_EQ(Cellular::kStateConnected, device_->state());
1010}
1011
Thieu Le5218cf22012-11-26 11:52:57 -08001012TEST_F(CellularTest, ModemStateChangeLostRegistration) {
1013 SetCellularType(Cellular::kTypeUniversal);
1014 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
1015 capability->registration_state_ = MM_MODEM_3GPP_REGISTRATION_STATE_HOME;
1016 EXPECT_TRUE(capability->IsRegistered());
Arman Uguray1ee93912013-09-24 21:24:10 -07001017 device_->set_modem_state(Cellular::kModemStateRegistered);
1018 device_->OnModemStateChanged(Cellular::kModemStateEnabled);
Thieu Le5218cf22012-11-26 11:52:57 -08001019 EXPECT_FALSE(capability->IsRegistered());
1020}
1021
Thieu Le37b90032012-05-15 15:18:41 -07001022TEST_F(CellularTest, StartModemCallback) {
Gary Morainbaeefdf2012-04-30 14:53:35 -07001023 EXPECT_CALL(*this, TestCallback(IsSuccess()));
1024 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -07001025 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
1026 Unretained(this)),
1027 Error(Error::kSuccess));
Gary Morainbaeefdf2012-04-30 14:53:35 -07001028 EXPECT_EQ(device_->state_, Cellular::kStateEnabled);
1029}
1030
Thieu Le37b90032012-05-15 15:18:41 -07001031TEST_F(CellularTest, StartModemCallbackFail) {
Gary Morainbaeefdf2012-04-30 14:53:35 -07001032 EXPECT_CALL(*this, TestCallback(IsFailure()));
1033 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -07001034 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
1035 Unretained(this)),
1036 Error(Error::kOperationFailed));
Gary Morainbaeefdf2012-04-30 14:53:35 -07001037 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
1038}
1039
Thieu Le37b90032012-05-15 15:18:41 -07001040TEST_F(CellularTest, StopModemCallback) {
1041 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -07001042 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -07001043 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
1044 Unretained(this)),
1045 Error(Error::kSuccess));
1046 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
1047 EXPECT_FALSE(device_->service_.get());
1048}
1049
1050TEST_F(CellularTest, StopModemCallbackFail) {
1051 EXPECT_CALL(*this, TestCallback(IsFailure()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -07001052 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -07001053 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
1054 Unretained(this)),
1055 Error(Error::kOperationFailed));
1056 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
1057 EXPECT_FALSE(device_->service_.get());
1058}
1059
Darin Petkove7c6ad32012-06-29 10:22:09 +02001060TEST_F(CellularTest, SetAllowRoaming) {
1061 EXPECT_FALSE(device_->allow_roaming_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -07001062 EXPECT_CALL(*modem_info_.mock_manager(), UpdateDevice(_));
Darin Petkove7c6ad32012-06-29 10:22:09 +02001063 Error error;
1064 device_->SetAllowRoaming(true, &error);
1065 EXPECT_TRUE(error.IsSuccess());
1066 EXPECT_TRUE(device_->allow_roaming_);
1067}
1068
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001069class TestRPCTaskDelegate :
1070 public RPCTaskDelegate,
1071 public base::SupportsWeakPtr<TestRPCTaskDelegate> {
1072 public:
1073 virtual void GetLogin(std::string *user, std::string *password) {}
1074 virtual void Notify(const std::string &reason,
1075 const std::map<std::string, std::string> &dict) {}
1076};
1077
1078TEST_F(CellularTest, LinkEventUpWithPPP) {
1079 // If PPP is running, don't run DHCP as well.
1080 TestRPCTaskDelegate task_delegate;
1081 base::Callback<void(pid_t, int)> death_callback;
1082 scoped_ptr<NiceMock<MockExternalTask>> mock_task(
1083 new NiceMock<MockExternalTask>(modem_info_.control_interface(),
1084 modem_info_.glib(),
1085 task_delegate.AsWeakPtr(),
1086 death_callback));
1087 EXPECT_CALL(*mock_task, OnDelete()).Times(AnyNumber());
1088 device_->ppp_task_ = mock_task.Pass();
1089 device_->state_ = Cellular::kStateConnected;
Paul Stewart75a68b92013-10-24 10:50:27 -07001090 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _, _))
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001091 .Times(0);
1092 EXPECT_CALL(*dhcp_config_, RequestIP()).Times(0);
1093 device_->LinkEvent(IFF_UP, 0);
1094}
1095
1096TEST_F(CellularTest, LinkEventUpWithoutPPP) {
1097 // If PPP is not running, fire up DHCP.
1098 device_->state_ = Cellular::kStateConnected;
Paul Stewart75a68b92013-10-24 10:50:27 -07001099 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _, _))
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001100 .WillOnce(Return(dhcp_config_));
1101 EXPECT_CALL(*dhcp_config_, RequestIP());
1102 EXPECT_CALL(*dhcp_config_, ReleaseIP(_)).Times(AnyNumber());
1103 device_->LinkEvent(IFF_UP, 0);
1104}
1105
mukesh agrawalf407d592013-07-31 11:37:57 -07001106TEST_F(CellularTest, StartPPP) {
1107 const int kPID = 234;
1108 EXPECT_FALSE(device_->ppp_task_);
1109 StartPPP(kPID);
1110}
1111
1112TEST_F(CellularTest, StartPPPAlreadyStarted) {
1113 const int kPID = 234;
1114 StartPPP(kPID);
1115
1116 const int kPID2 = 235;
1117 StartPPP(kPID2);
1118}
1119
mukesh agrawal35ec8402013-07-19 14:49:08 -07001120TEST_F(CellularTest, StartPPPAfterEthernetUp) {
1121 CellularService *service(SetService());
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001122 device_->state_ = Cellular::kStateLinked;
mukesh agrawal35ec8402013-07-19 14:49:08 -07001123 device_->set_ipconfig(dhcp_config_);
1124 device_->SelectService(service);
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001125 EXPECT_CALL(*dhcp_config_, ReleaseIP(_))
1126 .Times(AnyNumber())
1127 .WillRepeatedly(Return(true));
mukesh agrawalf407d592013-07-31 11:37:57 -07001128 const int kPID = 234;
1129 EXPECT_FALSE(device_->ppp_task_);
1130 StartPPP(kPID);
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001131 EXPECT_EQ(Cellular::kStateLinked, device_->state());
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001132}
1133
mukesh agrawal3ffe52c2013-06-20 15:21:29 -07001134TEST_F(CellularTest, GetLogin) {
1135 // Doesn't crash when there is no service.
1136 string username_to_pppd;
1137 string password_to_pppd;
1138 EXPECT_FALSE(device_->service());
1139 device_->GetLogin(&username_to_pppd, &password_to_pppd);
1140
1141 // Provides expected username and password in normal case.
1142 const char kFakeUsername[] = "fake-user";
1143 const char kFakePassword[] = "fake-password";
1144 CellularService &service(*SetService());
1145 service.ppp_username_ = kFakeUsername;
1146 service.ppp_password_ = kFakePassword;
1147 device_->GetLogin(&username_to_pppd, &password_to_pppd);
1148}
1149
mukesh agrawalf407d592013-07-31 11:37:57 -07001150TEST_F(CellularTest, Notify) {
1151 // Common setup.
1152 MockPPPDeviceFactory *ppp_device_factory =
1153 MockPPPDeviceFactory::GetInstance();
mukesh agrawalfc362912013-08-06 18:10:07 -07001154 const int kPID = 91;
mukesh agrawalf407d592013-07-31 11:37:57 -07001155 device_->ppp_device_factory_ = ppp_device_factory;
1156 SetMockService();
mukesh agrawalfc362912013-08-06 18:10:07 -07001157 StartPPP(kPID);
1158
1159 const map<string, string> kEmptyArgs;
1160 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1161 EXPECT_TRUE(device_->is_ppp_authenticating_);
1162 device_->Notify(kPPPReasonAuthenticated, kEmptyArgs);
1163 EXPECT_FALSE(device_->is_ppp_authenticating_);
mukesh agrawalf407d592013-07-31 11:37:57 -07001164
1165 // Normal connect.
1166 const string kInterfaceName("fake-device");
1167 const int kInterfaceIndex = 1;
1168 scoped_refptr<MockPPPDevice> ppp_device;
1169 map<string, string> ppp_config;
1170 ppp_device =
1171 new MockPPPDevice(modem_info_.control_interface(),
1172 NULL, NULL, NULL, kInterfaceName, kInterfaceIndex);
1173 ppp_config[kPPPInterfaceName] = kInterfaceName;
1174 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
1175 .WillOnce(Return(kInterfaceIndex));
1176 EXPECT_CALL(device_info_, RegisterDevice(_));
1177 EXPECT_CALL(*ppp_device_factory,
1178 CreatePPPDevice(_, _, _, _, kInterfaceName, kInterfaceIndex))
1179 .WillOnce(Return(ppp_device));
1180 EXPECT_CALL(*ppp_device, SetEnabled(true));
1181 EXPECT_CALL(*ppp_device, SelectService(_));
1182 EXPECT_CALL(*ppp_device, UpdateIPConfigFromPPP(ppp_config, false));
1183 device_->Notify(kPPPReasonConnect, ppp_config);
1184 Mock::VerifyAndClearExpectations(&device_info_);
1185 Mock::VerifyAndClearExpectations(ppp_device);
1186
1187 // Re-connect on same network device: if pppd sends us multiple connect
1188 // events, we behave sanely.
1189 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
1190 .WillOnce(Return(kInterfaceIndex));
1191 EXPECT_CALL(*ppp_device, SetEnabled(true));
1192 EXPECT_CALL(*ppp_device, SelectService(_));
1193 EXPECT_CALL(*ppp_device, UpdateIPConfigFromPPP(ppp_config, false));
1194 device_->Notify(kPPPReasonConnect, ppp_config);
1195 Mock::VerifyAndClearExpectations(&device_info_);
1196 Mock::VerifyAndClearExpectations(ppp_device);
1197
1198 // Re-connect on new network device: if we still have the PPPDevice
1199 // from a prior connect, this new connect should DTRT. This is
1200 // probably an unlikely case.
1201 const string kInterfaceName2("fake-device2");
1202 const int kInterfaceIndex2 = 2;
1203 scoped_refptr<MockPPPDevice> ppp_device2;
1204 map<string, string> ppp_config2;
1205 ppp_device2 =
1206 new MockPPPDevice(modem_info_.control_interface(),
1207 NULL, NULL, NULL, kInterfaceName2, kInterfaceIndex2);
1208 ppp_config2[kPPPInterfaceName] = kInterfaceName2;
1209 EXPECT_CALL(device_info_, GetIndex(kInterfaceName2))
1210 .WillOnce(Return(kInterfaceIndex2));
1211 EXPECT_CALL(device_info_,
1212 RegisterDevice(static_cast<DeviceRefPtr>(ppp_device2)));
1213 EXPECT_CALL(*ppp_device_factory,
1214 CreatePPPDevice(_, _, _, _, kInterfaceName2, kInterfaceIndex2))
1215 .WillOnce(Return(ppp_device2));
1216 EXPECT_CALL(*ppp_device, SelectService(ServiceRefPtr(nullptr)));
1217 EXPECT_CALL(*ppp_device2, SetEnabled(true));
1218 EXPECT_CALL(*ppp_device2, SelectService(_));
1219 EXPECT_CALL(*ppp_device2, UpdateIPConfigFromPPP(ppp_config2, false));
1220 device_->Notify(kPPPReasonConnect, ppp_config2);
1221 Mock::VerifyAndClearExpectations(&device_info_);
mukesh agrawalfc362912013-08-06 18:10:07 -07001222 Mock::VerifyAndClearExpectations(ppp_device);
mukesh agrawalf407d592013-07-31 11:37:57 -07001223 Mock::VerifyAndClearExpectations(ppp_device2);
1224
mukesh agrawalfc362912013-08-06 18:10:07 -07001225 // Disconnect should report unknown failure, since we had a
1226 // Notify(kPPPReasonAuthenticated, ...).
1227 EXPECT_CALL(*ppp_device2, SetServiceFailure(Service::kFailureUnknown));
1228 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1229 EXPECT_FALSE(device_->ppp_task_);
1230}
1231
1232TEST_F(CellularTest, PPPConnectionFailedBeforeAuth) {
1233 // Test that we properly set Service state in the case where pppd
1234 // disconnects before authenticating (as opposed to the Notify test,
1235 // where pppd disconnects after connecting).
1236 const int kPID = 52;
1237 const map<string, string> kEmptyArgs;
1238 MockCellularService *service = SetMockService();
1239 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001240
1241 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001242 EXPECT_CALL(*service, SetFailure(Service::kFailureUnknown));
1243 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1244 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001245 VerifyDisconnect();
mukesh agrawalfc362912013-08-06 18:10:07 -07001246}
1247
1248TEST_F(CellularTest, PPPConnectionFailedDuringAuth) {
1249 // Test that we properly set Service state in the case where pppd
1250 // disconnects during authentication (as opposed to the Notify test,
1251 // where pppd disconnects after connecting).
1252 const int kPID = 52;
1253 const map<string, string> kEmptyArgs;
1254 MockCellularService *service = SetMockService();
1255 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001256
1257 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001258 EXPECT_CALL(*service, SetFailure(Service::kFailurePPPAuth));
1259 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1260 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1261 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001262 VerifyDisconnect();
mukesh agrawalfc362912013-08-06 18:10:07 -07001263}
1264
1265TEST_F(CellularTest, PPPConnectionFailedAfterAuth) {
1266 // Test that we properly set Service state in the case where pppd
1267 // disconnects after authenticating, but before connecting (as
1268 // opposed to the Notify test, where pppd disconnects after
1269 // connecting).
1270 const int kPID = 52;
1271 const map<string, string> kEmptyArgs;
1272 MockCellularService *service = SetMockService();
1273 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001274
mukesh agrawalfc362912013-08-06 18:10:07 -07001275 EXPECT_CALL(*service, SetFailure(Service::kFailureUnknown));
mukesh agrawalee10f372013-08-14 14:07:11 -07001276 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001277 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1278 device_->Notify(kPPPReasonAuthenticated, kEmptyArgs);
1279 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
mukesh agrawalf407d592013-07-31 11:37:57 -07001280 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001281 VerifyDisconnect();
mukesh agrawalf407d592013-07-31 11:37:57 -07001282}
1283
1284TEST_F(CellularTest, OnPPPDied) {
1285 const int kPID = 1234;
1286 const int kExitStatus = 5;
mukesh agrawalee10f372013-08-14 14:07:11 -07001287 ExpectDisconnectCapabilityUniversal();
mukesh agrawalf407d592013-07-31 11:37:57 -07001288 device_->OnPPPDied(kPID, kExitStatus);
mukesh agrawalee10f372013-08-14 14:07:11 -07001289 VerifyDisconnect();
mukesh agrawalf407d592013-07-31 11:37:57 -07001290}
1291
mukesh agrawal5d851b12013-07-11 14:09:41 -07001292TEST_F(CellularTest, DropConnection) {
1293 device_->set_ipconfig(dhcp_config_);
1294 EXPECT_CALL(*dhcp_config_, ReleaseIP(_));
1295 device_->DropConnection();
1296 Mock::VerifyAndClearExpectations(dhcp_config_); // verify before dtor
1297 EXPECT_FALSE(device_->ipconfig());
1298}
1299
1300TEST_F(CellularTest, DropConnectionPPP) {
1301 scoped_refptr<MockPPPDevice> ppp_device(
1302 new MockPPPDevice(modem_info_.control_interface(),
1303 NULL, NULL, NULL, "fake_ppp0", -1));
1304 EXPECT_CALL(*ppp_device, DropConnection());
1305 device_->ppp_device_ = ppp_device;
1306 device_->DropConnection();
1307}
1308
mukesh agrawal0381f9a2013-07-11 16:41:52 -07001309TEST_F(CellularTest, ChangeServiceState) {
1310 MockCellularService *service(SetMockService());
1311 EXPECT_CALL(*service, SetState(_));
1312 EXPECT_CALL(*service, SetFailure(_));
1313 EXPECT_CALL(*service, SetFailureSilent(_));
Thieu Le43ce4d42013-10-04 16:08:55 -07001314 ON_CALL(*service, state()).WillByDefault(Return(Service::kStateUnknown));
mukesh agrawal0381f9a2013-07-11 16:41:52 -07001315
1316 // Without PPP, these should be handled by our selected_service().
1317 device_->SelectService(service);
1318 device_->SetServiceState(Service::kStateConfiguring);
1319 device_->SetServiceFailure(Service::kFailurePPPAuth);
1320 device_->SetServiceFailureSilent(Service::kFailureUnknown);
1321 Mock::VerifyAndClearExpectations(service); // before Cellular dtor
1322}
1323
1324TEST_F(CellularTest, ChangeServiceStatePPP) {
1325 MockCellularService *service(SetMockService());
1326 scoped_refptr<MockPPPDevice> ppp_device(
1327 new MockPPPDevice(modem_info_.control_interface(),
1328 NULL, NULL, NULL, "fake_ppp0", -1));
1329 EXPECT_CALL(*ppp_device, SetServiceState(_));
1330 EXPECT_CALL(*ppp_device, SetServiceFailure(_));
1331 EXPECT_CALL(*ppp_device, SetServiceFailureSilent(_));
1332 EXPECT_CALL(*service, SetState(_)).Times(0);
1333 EXPECT_CALL(*service, SetFailure(_)).Times(0);
1334 EXPECT_CALL(*service, SetFailureSilent(_)).Times(0);
1335 device_->ppp_device_ = ppp_device;
1336
1337 // With PPP, these should all be punted over to the |ppp_device|.
1338 // Note in particular that Cellular does not manipulate |service| in
1339 // this case.
1340 device_->SetServiceState(Service::kStateConfiguring);
1341 device_->SetServiceFailure(Service::kFailurePPPAuth);
1342 device_->SetServiceFailureSilent(Service::kFailureUnknown);
1343}
1344
mukesh agrawal5c8ed242013-10-04 11:59:58 -07001345TEST_F(CellularTest, StopPPPOnDisconnect) {
1346 const int kPID = 123;
mukesh agrawal5c8ed242013-10-04 11:59:58 -07001347 Error error;
mukesh agrawal28185512013-10-18 16:57:09 -07001348 StartPPP(kPID);
1349 FakeUpConnectedPPP();
1350 ExpectPPPStopped();
mukesh agrawal5c8ed242013-10-04 11:59:58 -07001351 device_->Disconnect(&error);
mukesh agrawal28185512013-10-18 16:57:09 -07001352 VerifyPPPStopped();
1353}
1354
1355TEST_F(CellularTest, StopPPPOnTermination) {
1356 const int kPID = 123;
1357 StartPPP(kPID);
1358 FakeUpConnectedPPP();
1359 ExpectPPPStopped();
1360 device_->StartTermination();
1361 VerifyPPPStopped();
1362}
1363
1364TEST_F(CellularTest, OnAfterResumeDisabledWantDisabled) {
1365 // The Device was disabled prior to resume, and the profile settings
1366 // indicate that the device should be disabled. We should leave
1367 // things alone.
1368
1369 // Initial state.
1370 mm1::MockModemProxy *mm1_proxy = SetupOnAfterResume();
1371 set_enabled_persistent(false);
1372 EXPECT_FALSE(device_->running());
1373 EXPECT_FALSE(device_->enabled_persistent());
1374 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1375
1376 // Resume, while device is disabled.
1377 EXPECT_CALL(*mm1_proxy, Enable(_, _, _, _)).Times(0);
1378 device_->OnAfterResume();
1379 EXPECT_FALSE(device_->running());
1380 EXPECT_FALSE(device_->enabled_persistent());
1381 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1382}
1383
1384TEST_F(CellularTest, OnAfterResumeDisableInProgressWantDisabled) {
1385 // The Device was not disabled prior to resume, but the profile
1386 // settings indicate that the device _should be_ disabled. Most
1387 // likely, we started disabling the device, but that did not
1388 // complete before we suspended. We should leave things alone.
1389
1390 // Initial state.
1391 mm1::MockModemProxy *mm1_proxy = SetupOnAfterResume();
1392 Error error;
1393 EXPECT_CALL(*mm1_proxy, Enable(true, _, _, _))
1394 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
1395 device_->SetEnabled(true);
1396 EXPECT_TRUE(device_->running());
1397 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
1398
1399 // Start disable.
1400 EXPECT_CALL(*modem_info_.mock_manager(), UpdateDevice(_));
1401 device_->SetEnabledPersistent(false, &error, ResultCallback());
1402 EXPECT_FALSE(device_->running()); // changes immediately
1403 EXPECT_FALSE(device_->enabled_persistent()); // changes immediately
1404 EXPECT_EQ(Cellular::kStateEnabled, device_->state_); // changes on completion
1405
1406 // Resume, with disable still in progress.
1407 device_->OnAfterResume();
1408 EXPECT_FALSE(device_->running());
1409 EXPECT_FALSE(device_->enabled_persistent());
1410 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
1411
1412 // Finish the disable operation.
1413 EXPECT_CALL(*mm1_proxy, Enable(false, _, _, _))
1414 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
1415 EXPECT_CALL(*mm1_proxy, SetPowerState(_, _, _, _))
1416 .WillOnce(Invoke(this, &CellularTest::InvokeSetPowerState));
1417 dispatcher_.DispatchPendingEvents();
1418 EXPECT_FALSE(device_->running());
1419 EXPECT_FALSE(device_->enabled_persistent());
1420 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1421}
1422
1423TEST_F(CellularTest, OnAfterResumeDisableQueuedWantEnabled) {
1424 // The Device was not disabled prior to resume, and the profile
1425 // settings indicate that the device should be enabled. In
1426 // particular, we went into suspend before we actually processed the
1427 // task queued by CellularCapabilityUniversal::StopModem.
1428 //
1429 // This is unlikely, and a case where we fail to do the right thing.
1430 // The tests exists to document this corner case, which we get wrong.
1431
1432 // Initial state.
1433 mm1::MockModemProxy *mm1_proxy = SetupOnAfterResume();
1434 EXPECT_CALL(*mm1_proxy, Enable(true, _, _, _))
1435 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
1436 device_->SetEnabled(true);
1437 EXPECT_TRUE(device_->running());
1438 EXPECT_TRUE(device_->enabled_persistent());
1439 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
1440
1441 // Start disable.
1442 device_->SetEnabled(false);
1443 EXPECT_FALSE(device_->running()); // changes immediately
1444 EXPECT_TRUE(device_->enabled_persistent()); // no change
1445 EXPECT_EQ(Cellular::kStateEnabled, device_->state_); // changes on completion
1446
1447 // Refresh proxies, since CellularCapabilityUniversal::StartModem wants
1448 // new proxies. Also, stash away references for later.
1449 PopulateProxies();
1450 SetCommonOnAfterResumeExpectations();
1451 mm1_proxy = mm1_proxy_.get();
1452 auto dbus_properties_proxy = dbus_properties_proxy_.get();
1453
1454 // Resume, with disable still in progress.
1455 EXPECT_CALL(*mm1_proxy, Enable(true, _, _, _))
1456 .WillOnce(Invoke(this, &CellularTest::InvokeEnableReturningWrongState));
1457 EXPECT_EQ(Cellular::kStateEnabled, device_->state_); // disable still pending
1458 device_->OnAfterResume();
1459 EXPECT_TRUE(device_->running()); // changes immediately
1460 EXPECT_TRUE(device_->enabled_persistent()); // no change
1461 EXPECT_EQ(Cellular::kStateDisabled, device_->state_); // by OnAfterResume
1462
1463 // Set up state that we need.
1464 DBusPropertiesMap modem_properties;
1465 DBus::Variant modem_state;
1466 modem_state.writer().append_int32(Cellular::kModemStateDisabled);
1467 modem_properties = DBusPropertiesMap{{MM_MODEM_PROPERTY_STATE, modem_state}};
1468
1469 // Let the disable complete.
1470 EXPECT_CALL(*mm1_proxy, Enable(false, _, _, _))
1471 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
1472 EXPECT_CALL(*mm1_proxy, SetPowerState(_, _, _, _))
1473 .WillOnce(Invoke(this, &CellularTest::InvokeSetPowerState));
1474 EXPECT_CALL(*dbus_properties_proxy, GetAll(_))
1475 .WillRepeatedly(Return(modem_properties));
1476 dispatcher_.DispatchPendingEvents();
1477 EXPECT_TRUE(device_->running()); // last changed by OnAfterResume
1478 EXPECT_TRUE(device_->enabled_persistent()); // last changed by OnAfterResume
1479 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1480
1481 // There's nothing queued up to restart the modem. Even though we
1482 // want to be running, we're stuck in the disabled state.
1483 dispatcher_.DispatchPendingEvents();
1484 EXPECT_TRUE(device_->running());
1485 EXPECT_TRUE(device_->enabled_persistent());
1486 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1487}
1488
1489TEST_F(CellularTest, OnAfterResumePowerDownInProgressWantEnabled) {
1490 // The Device was not fully disabled prior to resume, and the
1491 // profile settings indicate that the device should be enabled. In
1492 // this case, we have disabled the device, but are waiting for the
1493 // power-down (switch to low power) to complete.
1494 //
1495 // This test emulates the behavior of the Huawei E303 dongle, when
1496 // Manager::kTerminationActionsTimeoutMilliseconds is 9500
1497 // msec. (The dongle takes 10-11 seconds to go through the whole
1498 // disable, power-down sequence).
1499 //
1500 // Eventually, the power-down would complete, and the device would
1501 // be stuck in the disabled state. To counter-act that,
1502 // OnAfterResume tries to enable the device now, even though the
1503 // device is currently enabled.
1504
1505 // Initial state.
1506 mm1::MockModemProxy *mm1_proxy = SetupOnAfterResume();
1507 EXPECT_CALL(*mm1_proxy, Enable(true, _, _, _))
1508 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
1509 device_->SetEnabled(true);
1510 EXPECT_TRUE(device_->running());
1511 EXPECT_TRUE(device_->enabled_persistent());
1512 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
1513
1514 // Start disable.
1515 ResultCallback modem_proxy_enable_callback;
1516 EXPECT_CALL(*mm1_proxy, Enable(false, _, _, _))
1517 .WillOnce(SaveArg<2>(&modem_proxy_enable_callback));
1518 device_->SetEnabled(false);
1519 dispatcher_.DispatchPendingEvents(); // SetEnabled yields a deferred task
1520 EXPECT_FALSE(device_->running()); // changes immediately
1521 EXPECT_TRUE(device_->enabled_persistent()); // no change
1522 EXPECT_EQ(Cellular::kStateEnabled, device_->state_); // changes on completion
1523
1524 // Let the disable complete. That will trigger power-down.
1525 //
1526 // Note that, unlike for mm1_proxy->Enable, we don't save the
1527 // callback for mm1_proxy->SetPowerState. We expect the callback not
1528 // to be executed, as explained in the comment about having a fresh
1529 // proxy OnAfterResume, below.
1530 Error error;
1531 ASSERT_TRUE(error.IsSuccess());
1532 EXPECT_CALL(*mm1_proxy, SetPowerState(MM_MODEM_POWER_STATE_LOW, _, _, _));
1533 modem_proxy_enable_callback.Run(error);
1534
1535 // No response to power-down yet. It probably completed while the host
1536 // was asleep, and so the reply from the modem was lost.
1537
1538 // Refresh proxies, since CellularCapabilityUniversal::StartModem wants
1539 // new proxies. Also, stash away references for later.
1540 PopulateProxies();
1541 SetCommonOnAfterResumeExpectations();
1542 auto new_mm1_proxy = mm1_proxy_.get();
1543 auto dbus_properties_proxy = dbus_properties_proxy_.get();
1544
1545 // Resume.
1546 ResultCallback new_callback;
1547 EXPECT_EQ(Cellular::kStateEnabled, device_->state_); // disable still pending
1548 EXPECT_CALL(*new_mm1_proxy, Enable(true, _, _, _))
1549 .WillOnce(SaveArg<2>(&modem_proxy_enable_callback));
1550 device_->OnAfterResume();
1551 EXPECT_TRUE(device_->running()); // changes immediately
1552 EXPECT_TRUE(device_->enabled_persistent()); // no change
1553 EXPECT_EQ(Cellular::kStateDisabled, device_->state_); // by OnAfterResume
1554
1555 // We should have a fresh proxy OnAfterResume. Otherwise, we may get
1556 // confused when the SetPowerState call completes (either naturally,
1557 // or via a time-out from dbus-c++).
1558 //
1559 // The pointers must differ, because the new proxy is constructed
1560 // before the old one is destructed.
1561 EXPECT_FALSE(new_mm1_proxy == mm1_proxy);
1562
1563 // Set up state that we need.
1564 DBusPropertiesMap modem_properties;
1565 DBus::Variant modem_state;
1566 modem_state.writer().append_int32(Cellular::kModemStateEnabled);
1567 modem_properties = DBusPropertiesMap{{MM_MODEM_PROPERTY_STATE, modem_state}};
1568
1569 // Let the enable complete.
1570 ASSERT_TRUE(error.IsSuccess());
1571 EXPECT_CALL(*dbus_properties_proxy, GetAll(_))
1572 .WillRepeatedly(Return(modem_properties));
1573 ASSERT_TRUE(!modem_proxy_enable_callback.is_null());
1574 modem_proxy_enable_callback.Run(error);
1575 EXPECT_TRUE(device_->running());
1576 EXPECT_TRUE(device_->enabled_persistent());
1577 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
1578}
1579
1580TEST_F(CellularTest, OnAfterResumeDisabledWantEnabled) {
1581 // This is the ideal case. The disable process completed before
1582 // going into suspend.
1583 mm1::MockModemProxy *mm1_proxy = SetupOnAfterResume();
1584 EXPECT_FALSE(device_->running());
1585 EXPECT_TRUE(device_->enabled_persistent());
1586 EXPECT_EQ(Cellular::kStateDisabled, device_->state_);
1587
1588 // Resume.
1589 ResultCallback modem_proxy_enable_callback;
1590 EXPECT_CALL(*mm1_proxy, Enable(true, _, _, _))
1591 .WillOnce(SaveArg<2>(&modem_proxy_enable_callback));
1592 device_->OnAfterResume();
1593
1594 // Complete enable.
1595 Error error;
1596 ASSERT_TRUE(error.IsSuccess());
1597 modem_proxy_enable_callback.Run(error);
1598 EXPECT_TRUE(device_->running());
1599 EXPECT_TRUE(device_->enabled_persistent());
1600 EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
mukesh agrawal5c8ed242013-10-04 11:59:58 -07001601}
1602
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001603// Custom property setters should return false, and make no changes, if
1604// the new value is the same as the old value.
1605TEST_F(CellularTest, CustomSetterNoopChange) {
1606 Error error;
1607 EXPECT_FALSE(device_->allow_roaming_);
1608 EXPECT_FALSE(device_->SetAllowRoaming(false, &error));
1609 EXPECT_TRUE(error.IsSuccess());
1610}
1611
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -08001612TEST_F(CellularTest, ScanImmediateFailure) {
1613 Error error;
1614
1615 device_->set_found_networks(kTestNetworksCellular);
1616 EXPECT_CALL(*gsm_network_proxy_, Scan(&error, _, _))
1617 .WillOnce(Invoke(this, &CellularTest::InvokeScanFailed));
1618 EXPECT_FALSE(device_->scanning_);
1619 // |InitProxies| must be called before calling any functions on the
1620 // Capability*, to set up the modem proxies.
1621 // Warning: The test loses all references to the proxies when |InitProxies| is
1622 // called.
1623 GetCapabilityGSM()->InitProxies();
1624 device_->Scan(Device::kFullScan, &error, "");
1625 EXPECT_TRUE(error.IsFailure());
1626 EXPECT_FALSE(device_->scanning_);
1627 EXPECT_EQ(kTestNetworksCellular, device_->found_networks());
1628}
1629
1630TEST_F(CellularTest, ScanAsynchronousFailure) {
1631 Error error;
1632 ScanResultsCallback results_callback;
1633
1634 device_->set_found_networks(kTestNetworksCellular);
1635 EXPECT_CALL(*gsm_network_proxy_, Scan(&error, _, _))
1636 .WillOnce(DoAll(Invoke(this, &CellularTest::InvokeScanInitiated),
1637 SaveArg<1>(&results_callback)));
1638 EXPECT_FALSE(device_->scanning_);
1639 // |InitProxies| must be called before calling any functions on the
1640 // Capability*, to set up the modem proxies.
1641 // Warning: The test loses all references to the proxies when |InitProxies| is
1642 // called.
1643 GetCapabilityGSM()->InitProxies();
1644 device_->Scan(Device::kFullScan, &error, "");
1645 EXPECT_TRUE(error.IsOngoing());
1646 EXPECT_TRUE(device_->scanning_);
1647
1648 // Asynchronously fail the scan.
1649 error.Populate(Error::kOperationFailed);
1650 results_callback.Run(kTestNetworksGSM, error);
1651 EXPECT_FALSE(device_->scanning_);
1652 EXPECT_TRUE(device_->found_networks().empty());
1653}
1654
1655TEST_F(CellularTest, ScanSuccess) {
1656 Error error;
1657 ScanResultsCallback results_callback;
1658
1659 device_->clear_found_networks();
1660 EXPECT_CALL(*gsm_network_proxy_, Scan(&error, _, _))
1661 .WillOnce(DoAll(Invoke(this, &CellularTest::InvokeScanInitiated),
1662 SaveArg<1>(&results_callback)));
1663 EXPECT_FALSE(device_->scanning_);
1664 // |InitProxies| must be called before calling any functions on the
1665 // Capability*, to set up the modem proxies.
1666 // Warning: The test loses all references to the proxies when |InitProxies| is
1667 // called.
1668 GetCapabilityGSM()->InitProxies();
1669 device_->Scan(Device::kFullScan, &error, "");
1670 EXPECT_TRUE(error.IsOngoing());
1671 EXPECT_TRUE(device_->scanning_);
1672
1673 // Successfully complete the scan.
1674 const GSMScanResults gsm_results{};
1675 error.Populate(Error::kSuccess);
1676 results_callback.Run(kTestNetworksGSM, error);
1677 EXPECT_FALSE(device_->scanning_);
1678 EXPECT_EQ(kTestNetworksCellular, device_->found_networks());
1679}
1680
Ben Chan539ab022014-02-03 16:34:57 -08001681TEST_F(CellularTest, EstablishLinkDHCP) {
1682 scoped_ptr<CellularBearer> bearer(
1683 new CellularBearer(&proxy_factory_, "", ""));
1684 bearer->set_ipv4_config_method(IPConfig::kMethodDHCP);
1685 SetCapabilityUniversalActiveBearer(bearer.Pass());
1686 device_->state_ = Cellular::kStateConnected;
1687
1688 MockCellularService *service = SetMockService();
1689 ON_CALL(*service, state()).WillByDefault(Return(Service::kStateUnknown));
1690
1691 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
1692 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
1693 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _, _))
1694 .WillOnce(Return(dhcp_config_));
1695 EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
1696 EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
1697 device_->EstablishLink();
1698 EXPECT_EQ(service, device_->selected_service());
1699 Mock::VerifyAndClearExpectations(service); // before Cellular dtor
1700}
1701
1702TEST_F(CellularTest, EstablishLinkPPP) {
1703 scoped_ptr<CellularBearer> bearer(
1704 new CellularBearer(&proxy_factory_, "", ""));
1705 bearer->set_ipv4_config_method(IPConfig::kMethodPPP);
1706 SetCapabilityUniversalActiveBearer(bearer.Pass());
1707 device_->state_ = Cellular::kStateConnected;
1708
1709 const int kPID = 123;
1710 MockGLib &mock_glib(*dynamic_cast<MockGLib *>(modem_info_.glib()));
1711 EXPECT_CALL(mock_glib, ChildWatchAdd(kPID, _, _));
1712 EXPECT_CALL(mock_glib, SpawnAsync(_, _, _, _, _, _, _, _))
1713 .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
1714 device_->EstablishLink();
1715 EXPECT_FALSE(device_->ipconfig()); // No DHCP client.
1716 EXPECT_FALSE(device_->selected_service());
1717 EXPECT_FALSE(device_->is_ppp_authenticating_);
1718 EXPECT_TRUE(device_->ppp_task_);
1719}
1720
1721TEST_F(CellularTest, EstablishLinkStatic) {
1722 IPAddress::Family kAddressFamily = IPAddress::kFamilyIPv4;
1723 const char kAddress[] = "10.0.0.1";
1724 const char kGateway[] = "10.0.0.254";
1725 const int32 kSubnetPrefix = 16;
1726 const char *const kDNS[] = {"10.0.0.2", "8.8.4.4", "8.8.8.8"};
1727
1728 scoped_ptr<IPConfig::Properties> ipconfig_properties(
1729 new IPConfig::Properties);
1730 ipconfig_properties->address_family = kAddressFamily;
1731 ipconfig_properties->address = kAddress;
1732 ipconfig_properties->gateway = kGateway;
1733 ipconfig_properties->subnet_prefix = kSubnetPrefix;
1734 ipconfig_properties->dns_servers = vector<string>{kDNS[0], kDNS[1], kDNS[2]};
1735
1736 scoped_ptr<CellularBearer> bearer(
1737 new CellularBearer(&proxy_factory_, "", ""));
1738 bearer->set_ipv4_config_method(IPConfig::kMethodStatic);
1739 bearer->set_ipv4_config_properties(ipconfig_properties.Pass());
1740 SetCapabilityUniversalActiveBearer(bearer.Pass());
1741 device_->state_ = Cellular::kStateConnected;
1742
1743 MockCellularService *service = SetMockService();
1744 ON_CALL(*service, state()).WillByDefault(Return(Service::kStateUnknown));
1745
1746 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
1747 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
1748 EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
1749 device_->EstablishLink();
1750 EXPECT_EQ(service, device_->selected_service());
1751 ASSERT_TRUE(device_->ipconfig());
1752 EXPECT_EQ(kAddressFamily, device_->ipconfig()->properties().address_family);
1753 EXPECT_EQ(kAddress, device_->ipconfig()->properties().address);
1754 EXPECT_EQ(kGateway, device_->ipconfig()->properties().gateway);
1755 EXPECT_EQ(kSubnetPrefix, device_->ipconfig()->properties().subnet_prefix);
1756 ASSERT_EQ(3, device_->ipconfig()->properties().dns_servers.size());
1757 EXPECT_EQ(kDNS[0], device_->ipconfig()->properties().dns_servers[0]);
1758 EXPECT_EQ(kDNS[1], device_->ipconfig()->properties().dns_servers[1]);
1759 EXPECT_EQ(kDNS[2], device_->ipconfig()->properties().dns_servers[2]);
1760 Mock::VerifyAndClearExpectations(service); // before Cellular dtor
1761}
1762
Chris Masoneb925cc82011-06-22 15:39:57 -07001763} // namespace shill