blob: e1d0a3febf3627066e4192edfe64d6c152b5db0c [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
Darin Petkovae0c64e2011-11-15 15:50:27 +010014#include "shill/cellular_capability_cdma.h"
Jason Glasgow82f9ab32012-04-04 14:27:19 -040015#include "shill/cellular_capability_classic.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010016#include "shill/cellular_capability_gsm.h"
Ben Chan09fa2a02012-11-07 22:09:09 -080017#include "shill/cellular_capability_universal.h"
Darin Petkovd9661952011-08-03 16:25:42 -070018#include "shill/cellular_service.h"
Darin Petkov4d6d9412011-08-24 13:19:54 -070019#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070020#include "shill/event_dispatcher.h"
Thieu Le37b90032012-05-15 15:18:41 -070021#include "shill/mock_cellular_service.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070022#include "shill/mock_device_info.h"
Darin Petkov77cb6812011-08-15 16:19:41 -070023#include "shill/mock_dhcp_config.h"
24#include "shill/mock_dhcp_provider.h"
mukesh agrawalfbc40d22013-06-28 00:25:13 -070025#include "shill/mock_external_task.h"
mukesh agrawalf407d592013-07-31 11:37:57 -070026#include "shill/mock_mm1_modem_simple_proxy.h"
Darin Petkovbec79a22011-08-01 14:47:17 -070027#include "shill/mock_modem_cdma_proxy.h"
Darin Petkov975b5e72011-08-30 11:48:08 -070028#include "shill/mock_modem_gsm_card_proxy.h"
Darin Petkova1e0a1c2011-08-25 15:08:33 -070029#include "shill/mock_modem_gsm_network_proxy.h"
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070030#include "shill/mock_modem_info.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070031#include "shill/mock_modem_proxy.h"
Darin Petkove604f702011-07-28 15:51:17 -070032#include "shill/mock_modem_simple_proxy.h"
mukesh agrawal5d851b12013-07-11 14:09:41 -070033#include "shill/mock_ppp_device.h"
mukesh agrawalf407d592013-07-31 11:37:57 -070034#include "shill/mock_ppp_device_factory.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070035#include "shill/mock_rtnl_handler.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070036#include "shill/property_store_unittest.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070037#include "shill/proxy_factory.h"
mukesh agrawalfbc40d22013-06-28 00:25:13 -070038#include "shill/rpc_task.h" // for RpcTaskDelegate
Chris Masoneb925cc82011-06-22 15:39:57 -070039
Ben Chan09fa2a02012-11-07 22:09:09 -080040// mm/mm-modem.h must be included after cellular_capability_universal.h
41// in order to allow MM_MODEM_CDMA_* to be defined properly.
42#include <mm/mm-modem.h>
43
Eric Shienbrood9a245532012-03-07 14:20:39 -050044using base::Bind;
45using base::Unretained;
Darin Petkovc0865312011-09-16 15:31:20 -070046using std::map;
Chris Masoneb925cc82011-06-22 15:39:57 -070047using std::string;
Eric Shienbrood7fce52c2012-04-13 19:11:02 -040048using std::vector;
Darin Petkovbec79a22011-08-01 14:47:17 -070049using testing::_;
Chris Masoneb9c00592011-10-06 13:10:39 -070050using testing::AnyNumber;
mukesh agrawalf407d592013-07-31 11:37:57 -070051using testing::DoAll;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050052using testing::Invoke;
Arman Ugurayf84a4242013-04-09 20:01:07 -070053using testing::Mock;
Darin Petkov0828f5f2011-08-11 10:18:52 -070054using testing::NiceMock;
Darin Petkove604f702011-07-28 15:51:17 -070055using testing::Return;
Darin Petkovbec79a22011-08-01 14:47:17 -070056using testing::SetArgumentPointee;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050057using testing::Unused;
Chris Masoneb925cc82011-06-22 15:39:57 -070058
59namespace shill {
60
Eric Shienbrood9a245532012-03-07 14:20:39 -050061MATCHER(IsSuccess, "") {
62 return arg.IsSuccess();
63}
64
Gary Morainbaeefdf2012-04-30 14:53:35 -070065MATCHER(IsFailure, "") {
66 return arg.IsFailure();
67}
68
Darin Petkov0828f5f2011-08-11 10:18:52 -070069class CellularPropertyTest : public PropertyStoreTest {
70 public:
71 CellularPropertyTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070072 : modem_info_(control_interface(),
73 dispatcher(),
74 metrics(),
75 manager(),
76 glib()),
77 device_(new Cellular(&modem_info_,
Darin Petkove9d12e02011-07-27 15:09:37 -070078 "usb0",
Chris Masone626719f2011-08-18 16:58:48 -070079 "00:01:02:03:04:05",
Darin Petkove9d12e02011-07-27 15:09:37 -070080 3,
Ben Chan3ecdf822012-08-06 12:29:23 -070081 Cellular::kTypeCDMA,
Darin Petkov0828f5f2011-08-11 10:18:52 -070082 "",
Darin Petkov137884a2011-10-26 18:52:47 +020083 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040084 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070085 ProxyFactory::GetInstance())) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -070086 virtual ~CellularPropertyTest() {}
Darin Petkove9d12e02011-07-27 15:09:37 -070087
Chris Masoneb925cc82011-06-22 15:39:57 -070088 protected:
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070089 MockModemInfo modem_info_;
Darin Petkov0828f5f2011-08-11 10:18:52 -070090 DeviceRefPtr device_;
Chris Masoneb925cc82011-06-22 15:39:57 -070091};
92
Darin Petkov0828f5f2011-08-11 10:18:52 -070093TEST_F(CellularPropertyTest, Contains) {
Ben Chan7ea768e2013-09-20 15:08:40 -070094 EXPECT_TRUE(device_->store().Contains(kNameProperty));
mukesh agrawalde29fa82011-09-16 16:16:36 -070095 EXPECT_FALSE(device_->store().Contains(""));
Chris Masoneb925cc82011-06-22 15:39:57 -070096}
97
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080098TEST_F(CellularPropertyTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -070099 {
100 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700101 ::DBus::Variant allow_roaming;
102 allow_roaming.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800103 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700104 device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700105 kCellularAllowRoamingProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700106 allow_roaming,
Chris Masonea8a2c252011-06-27 22:16:30 -0700107 &error));
108 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700109 // Ensure that attempting to write a R/O property returns InvalidArgs error.
110 {
111 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800112 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700113 kAddressProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800114 PropertyStoreTest::kStringV,
115 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700116 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700117 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700118 }
119 {
120 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800121 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
Ben Chan7ea768e2013-09-20 15:08:40 -0700122 kCarrierProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800123 PropertyStoreTest::kStringV,
124 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700125 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700126 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700127 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700128}
129
Darin Petkov0828f5f2011-08-11 10:18:52 -0700130class CellularTest : public testing::Test {
131 public:
132 CellularTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700133 : modem_info_(NULL, &dispatcher_, NULL, NULL, NULL),
134 device_info_(modem_info_.control_interface(), &dispatcher_,
135 modem_info_.metrics(), modem_info_.manager()),
136 dhcp_config_(new MockDHCPConfig(modem_info_.control_interface(),
Paul Stewartd408fdf2012-05-07 17:15:57 -0700137 kTestDeviceName)),
Ben Chan3ecdf822012-08-06 12:29:23 -0700138 create_gsm_card_proxy_from_factory_(false),
139 proxy_(new MockModemProxy()),
140 simple_proxy_(new MockModemSimpleProxy()),
141 cdma_proxy_(new MockModemCDMAProxy()),
142 gsm_card_proxy_(new MockModemGSMCardProxy()),
143 gsm_network_proxy_(new MockModemGSMNetworkProxy()),
mukesh agrawalf407d592013-07-31 11:37:57 -0700144 mm1_simple_proxy_(new mm1::MockModemSimpleProxy()),
Ben Chan3ecdf822012-08-06 12:29:23 -0700145 proxy_factory_(this),
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700146 device_(new Cellular(&modem_info_,
Darin Petkov77cb6812011-08-15 16:19:41 -0700147 kTestDeviceName,
Chris Masone626719f2011-08-18 16:58:48 -0700148 kTestDeviceAddress,
Darin Petkov0828f5f2011-08-11 10:18:52 -0700149 3,
150 Cellular::kTypeGSM,
151 kDBusOwner,
Jason Glasgowa585fc32012-06-06 11:04:09 -0400152 kDBusService,
Darin Petkov137884a2011-10-26 18:52:47 +0200153 kDBusPath,
Thieu Lece4483e2013-01-23 15:12:03 -0800154 &proxy_factory_)) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700155 modem_info_.metrics()->RegisterDevice(device_->interface_index(),
156 Technology::kCellular);
Darin Petkov137884a2011-10-26 18:52:47 +0200157 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700158
159 virtual void SetUp() {
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700160 static_cast<Device *>(device_)->rtnl_handler_ = &rtnl_handler_;
Darin Petkov77cb6812011-08-15 16:19:41 -0700161 device_->set_dhcp_provider(&dhcp_provider_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700162 EXPECT_CALL(*modem_info_.mock_manager(), device_info())
163 .WillRepeatedly(Return(&device_info_));
164 EXPECT_CALL(*modem_info_.mock_manager(), DeregisterService(_))
165 .Times(AnyNumber());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700166 }
167
168 virtual void TearDown() {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500169 device_->DestroyIPConfig();
Darin Petkovfb0625e2012-01-16 13:05:56 +0100170 device_->state_ = Cellular::kStateDisabled;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500171 device_->capability_->ReleaseProxies();
Darin Petkov77cb6812011-08-15 16:19:41 -0700172 device_->set_dhcp_provider(NULL);
mukesh agrawal0381f9a2013-07-11 16:41:52 -0700173 // Break cycle between Cellular and CellularService.
174 device_->service_ = NULL;
175 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700176 }
177
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700178 void InitProviderDB() {
179 modem_info_.SetProviderDB(kTestMobileProviderDBPath);
180 }
181
Eric Shienbrood9a245532012-03-07 14:20:39 -0500182 void InvokeEnable(bool enable, Error *error,
183 const ResultCallback &callback, int timeout) {
184 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500185 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500186 void InvokeGetSignalQuality(Error *error,
187 const SignalQualityCallback &callback,
188 int timeout) {
189 callback.Run(kStrength, Error());
190 }
191 void InvokeGetModemStatus(Error *error,
192 const DBusPropertyMapCallback &callback,
193 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500194 DBusPropertiesMap props;
195 props["carrier"].writer().append_string(kTestCarrier);
196 props["unknown-property"].writer().append_string("irrelevant-value");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500197 callback.Run(props, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500198 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500199 void InvokeGetModemInfo(Error *error, const ModemInfoCallback &callback,
200 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500201 static const char kManufacturer[] = "Company";
202 static const char kModelID[] = "Gobi 2000";
203 static const char kHWRev[] = "A00B1234";
204 ModemHardwareInfo info;
205 info._1 = kManufacturer;
206 info._2 = kModelID;
207 info._3 = kHWRev;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500208 callback.Run(info, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500209 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500210 void InvokeGetRegistrationState1X(Error *error,
211 const RegistrationStateCallback &callback,
212 int timeout) {
213 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
214 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
215 Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500216 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500217 void InvokeGetIMEI(Error *error, const GSMIdentifierCallback &callback,
218 int timeout) {
219 callback.Run(kIMEI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500220 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500221 void InvokeGetIMSI(Error *error, const GSMIdentifierCallback &callback,
222 int timeout) {
223 callback.Run(kIMSI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500224 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500225 void InvokeGetMSISDN(Error *error, const GSMIdentifierCallback &callback,
226 int timeout) {
227 callback.Run(kMSISDN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500228 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500229 void InvokeGetSPN(Error *error, const GSMIdentifierCallback &callback,
230 int timeout) {
Darin Petkova4ca3c32012-08-17 16:05:24 +0200231 callback.Run(kTestCarrierSPN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500232 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500233 void InvokeGetRegistrationInfo(Error *error,
234 const RegistrationInfoCallback &callback,
235 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500236 static const char kNetworkID[] = "22803";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500237 callback.Run(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING,
238 kNetworkID, kTestCarrier, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500239 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500240 void InvokeRegister(const string &network_id,
241 Error *error,
242 const ResultCallback &callback,
243 int timeout) {
244 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500245 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500246 void InvokeGetRegistrationState(Error *error,
247 const RegistrationStateCallback &callback,
248 int timeout) {
249 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
250 MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
251 Error());
252 }
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400253 void InvokeGetRegistrationStateUnregistered(
254 Error *error,
255 const RegistrationStateCallback &callback,
256 int timeout) {
257 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
258 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
259 Error());
Arman Uguray539c4232012-09-11 10:00:22 -0700260 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500261 void InvokeConnect(DBusPropertiesMap props, Error *error,
262 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400263 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500264 callback.Run(Error());
265 }
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400266 void InvokeConnectFail(DBusPropertiesMap props, Error *error,
Thieu Leb5954a22012-05-18 10:37:34 -0700267 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400268 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
269 callback.Run(Error(Error::kNotOnHomeNetwork));
270 }
Thieu Leb5954a22012-05-18 10:37:34 -0700271 void InvokeConnectFailNoService(DBusPropertiesMap props, Error *error,
272 const ResultCallback &callback, int timeout) {
273 device_->service_ = NULL;
274 callback.Run(Error(Error::kNotOnHomeNetwork));
275 }
Thieu Led4974cd2013-05-23 10:39:28 -0700276 void InvokeConnectSuccessNoService(DBusPropertiesMap props, Error *error,
277 const ResultCallback &callback,
278 int timeout) {
279 device_->service_ = NULL;
280 callback.Run(Error());
281 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500282 void InvokeDisconnect(Error *error, const ResultCallback &callback,
283 int timeout) {
284 if (!callback.is_null())
285 callback.Run(Error());
286 }
Arman Uguray539c4232012-09-11 10:00:22 -0700287 void InvokeDisconnectFail(Error *error, const ResultCallback &callback,
288 int timeout) {
289 error->Populate(Error::kOperationFailed);
290 if (!callback.is_null())
291 callback.Run(*error);
292 }
mukesh agrawalf407d592013-07-31 11:37:57 -0700293 void InvokeDisconnectMM1(const ::DBus::Path &bearer, Error *error,
294 const ResultCallback &callback, int timeout) {
295 if (!callback.is_null())
296 callback.Run(Error());
297 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500298
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400299 void ExpectCdmaStartModem(string network_technology) {
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400300 if (!device_->IsUnderlyingDeviceEnabled())
301 EXPECT_CALL(*proxy_,
302 Enable(true, _, _, CellularCapability::kTimeoutEnable))
303 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400304 EXPECT_CALL(*simple_proxy_,
305 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
306 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
307 EXPECT_CALL(*proxy_,
308 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
309 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Ben Chan7ea768e2013-09-20 15:08:40 -0700310 if (network_technology == kNetworkTechnology1Xrtt)
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400311 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400312 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState1X));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400313 else
314 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400315 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400316 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
317 .Times(2)
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400318 .WillRepeatedly(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400319 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700320 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400321 }
322
mukesh agrawalee10f372013-08-14 14:07:11 -0700323 void ExpectDisconnectCapabilityUniversal() {
324 SetCellularType(Cellular::kTypeUniversal);
325 device_->state_ = Cellular::kStateConnected;
326 EXPECT_CALL(*mm1_simple_proxy_, Disconnect(_, _, _, _))
327 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnectMM1));
328 GetCapabilityUniversal()->modem_simple_proxy_.reset(
329 mm1_simple_proxy_.release());
330 GetCapabilityUniversal()->bearer_path_ = "/fake/path";
331 }
332
333 void VerifyDisconnect() {
334 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
335 }
336
mukesh agrawalf407d592013-07-31 11:37:57 -0700337 void StartPPP(int pid) {
338 MockGLib &mock_glib(*dynamic_cast<MockGLib *>(modem_info_.glib()));
339 EXPECT_CALL(mock_glib, ChildWatchAdd(pid, _, _));
340 EXPECT_CALL(mock_glib, SpawnAsync(_, _, _, _, _, _, _, _))
341 .WillOnce(DoAll(SetArgumentPointee<6>(pid), Return(true)));
342 device_->StartPPP("fake_serial_device");
343 EXPECT_FALSE(device_->ipconfig()); // No DHCP client.
344 EXPECT_FALSE(device_->selected_service());
mukesh agrawalfc362912013-08-06 18:10:07 -0700345 EXPECT_FALSE(device_->is_ppp_authenticating_);
mukesh agrawalf407d592013-07-31 11:37:57 -0700346 EXPECT_TRUE(device_->ppp_task_);
347 Mock::VerifyAndClearExpectations(&mock_glib);
348 }
349
Eric Shienbrood9a245532012-03-07 14:20:39 -0500350 MOCK_METHOD1(TestCallback, void(const Error &error));
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500351
Darin Petkov0828f5f2011-08-11 10:18:52 -0700352 protected:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500353 static const char kTestDeviceName[];
354 static const char kTestDeviceAddress[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500355 static const char kDBusOwner[];
Jason Glasgowa585fc32012-06-06 11:04:09 -0400356 static const char kDBusService[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500357 static const char kDBusPath[];
358 static const char kTestCarrier[];
Darin Petkova4ca3c32012-08-17 16:05:24 +0200359 static const char kTestCarrierSPN[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500360 static const char kMEID[];
361 static const char kIMEI[];
362 static const char kIMSI[];
363 static const char kMSISDN[];
364 static const char kTestMobileProviderDBPath[];
Eric Shienbrood9a245532012-03-07 14:20:39 -0500365 static const int kStrength;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500366
Darin Petkov0828f5f2011-08-11 10:18:52 -0700367 class TestProxyFactory : public ProxyFactory {
368 public:
Paul Stewart7355ce12011-09-02 10:47:01 -0700369 explicit TestProxyFactory(CellularTest *test) : test_(test) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -0700370
mukesh agrawal1830fa12011-09-26 14:31:40 -0700371 virtual ModemProxyInterface *CreateModemProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700372 const string &/*path*/,
373 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700374 return test_->proxy_.release();
375 }
376
377 virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700378 const string &/*path*/,
379 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700380 return test_->simple_proxy_.release();
381 }
382
383 virtual ModemCDMAProxyInterface *CreateModemCDMAProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700384 const string &/*path*/,
385 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700386 return test_->cdma_proxy_.release();
387 }
388
Darin Petkov975b5e72011-08-30 11:48:08 -0700389 virtual ModemGSMCardProxyInterface *CreateModemGSMCardProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700390 const string &/*path*/,
391 const string &/*service*/) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700392 // TODO(benchan): This code conditionally returns a NULL pointer to avoid
393 // CellularCapabilityGSM::InitProperties (and thus
394 // CellularCapabilityGSM::GetIMSI) from being called during the
395 // construction. Remove this workaround after refactoring the tests.
396 return test_->create_gsm_card_proxy_from_factory_ ?
397 test_->gsm_card_proxy_.release() : NULL;
Darin Petkov975b5e72011-08-30 11:48:08 -0700398 }
399
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700400 virtual ModemGSMNetworkProxyInterface *CreateModemGSMNetworkProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700401 const string &/*path*/,
402 const string &/*service*/) {
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700403 return test_->gsm_network_proxy_.release();
404 }
405
Darin Petkov0828f5f2011-08-11 10:18:52 -0700406 private:
407 CellularTest *test_;
408 };
Darin Petkov0828f5f2011-08-11 10:18:52 -0700409 void StartRTNLHandler();
410 void StopRTNLHandler();
411
Ben Chan3ecdf822012-08-06 12:29:23 -0700412 void AllowCreateGSMCardProxyFromFactory() {
413 create_gsm_card_proxy_from_factory_ = true;
414 }
415
Darin Petkov721ac932011-11-16 15:43:09 +0100416 void SetCellularType(Cellular::Type type) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700417 device_->InitCapability(type);
Darin Petkov721ac932011-11-16 15:43:09 +0100418 }
419
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400420 CellularCapabilityClassic *GetCapabilityClassic() {
421 return dynamic_cast<CellularCapabilityClassic *>(
422 device_->capability_.get());
423 }
424
Darin Petkovae0c64e2011-11-15 15:50:27 +0100425 CellularCapabilityCDMA *GetCapabilityCDMA() {
426 return dynamic_cast<CellularCapabilityCDMA *>(device_->capability_.get());
427 }
428
429 CellularCapabilityGSM *GetCapabilityGSM() {
430 return dynamic_cast<CellularCapabilityGSM *>(device_->capability_.get());
431 }
432
Ben Chan09fa2a02012-11-07 22:09:09 -0800433 CellularCapabilityUniversal *GetCapabilityUniversal() {
434 return dynamic_cast<CellularCapabilityUniversal *>(
435 device_->capability_.get());
436 }
437
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700438 // Different tests simulate a cellular service being set using a real /mock
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700439 // service.
Arman Ugurayf84a4242013-04-09 20:01:07 -0700440 CellularService *SetService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700441 device_->service_ = new CellularService(&modem_info_, device_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700442 return device_->service_;
443 }
Arman Ugurayf84a4242013-04-09 20:01:07 -0700444 MockCellularService *SetMockService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700445 device_->service_ = new MockCellularService(&modem_info_, device_);
446 return static_cast<MockCellularService *>(device_->service_.get());
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700447 }
448
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700449 EventDispatcher dispatcher_;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700450 MockModemInfo modem_info_;
Chris Masone2ae797d2011-08-23 20:41:00 -0700451 MockDeviceInfo device_info_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700452 NiceMock<MockRTNLHandler> rtnl_handler_;
453
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500454 MockDHCPProvider dhcp_provider_;
455 scoped_refptr<MockDHCPConfig> dhcp_config_;
456
Ben Chan3ecdf822012-08-06 12:29:23 -0700457 bool create_gsm_card_proxy_from_factory_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700458 scoped_ptr<MockModemProxy> proxy_;
459 scoped_ptr<MockModemSimpleProxy> simple_proxy_;
460 scoped_ptr<MockModemCDMAProxy> cdma_proxy_;
Darin Petkov975b5e72011-08-30 11:48:08 -0700461 scoped_ptr<MockModemGSMCardProxy> gsm_card_proxy_;
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700462 scoped_ptr<MockModemGSMNetworkProxy> gsm_network_proxy_;
mukesh agrawalf407d592013-07-31 11:37:57 -0700463 scoped_ptr<mm1::MockModemSimpleProxy> mm1_simple_proxy_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700464 TestProxyFactory proxy_factory_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700465 CellularRefPtr device_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700466};
467
Darin Petkov77cb6812011-08-15 16:19:41 -0700468const char CellularTest::kTestDeviceName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700469const char CellularTest::kTestDeviceAddress[] = "00:01:02:03:04:05";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700470const char CellularTest::kDBusOwner[] = ":1.19";
Jason Glasgowa585fc32012-06-06 11:04:09 -0400471const char CellularTest::kDBusService[] = "org.chromium.ModemManager";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700472const char CellularTest::kDBusPath[] = "/org/chromium/ModemManager/Gobi/0";
Darin Petkov51489002011-08-18 13:13:20 -0700473const char CellularTest::kTestCarrier[] = "The Cellular Carrier";
Darin Petkova4ca3c32012-08-17 16:05:24 +0200474const char CellularTest::kTestCarrierSPN[] = "Home Provider";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500475const char CellularTest::kMEID[] = "01234567EF8901";
Darin Petkov975b5e72011-08-30 11:48:08 -0700476const char CellularTest::kIMEI[] = "987654321098765";
477const char CellularTest::kIMSI[] = "123456789012345";
478const char CellularTest::kMSISDN[] = "12345678901";
Darin Petkov137884a2011-10-26 18:52:47 +0200479const char CellularTest::kTestMobileProviderDBPath[] =
480 "provider_db_unittest.bfd";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500481const int CellularTest::kStrength = 90;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700482
Darin Petkove9d12e02011-07-27 15:09:37 -0700483TEST_F(CellularTest, GetStateString) {
Darin Petkovcc044422011-08-17 13:30:06 -0700484 EXPECT_EQ("CellularStateDisabled",
Ben Chanf45b3232013-10-08 20:54:01 -0700485 Cellular::GetStateString(Cellular::kStateDisabled));
Darin Petkovcc044422011-08-17 13:30:06 -0700486 EXPECT_EQ("CellularStateEnabled",
Ben Chanf45b3232013-10-08 20:54:01 -0700487 Cellular::GetStateString(Cellular::kStateEnabled));
Darin Petkovcc044422011-08-17 13:30:06 -0700488 EXPECT_EQ("CellularStateRegistered",
Ben Chanf45b3232013-10-08 20:54:01 -0700489 Cellular::GetStateString(Cellular::kStateRegistered));
Darin Petkovcc044422011-08-17 13:30:06 -0700490 EXPECT_EQ("CellularStateConnected",
Ben Chanf45b3232013-10-08 20:54:01 -0700491 Cellular::GetStateString(Cellular::kStateConnected));
Darin Petkovcc044422011-08-17 13:30:06 -0700492 EXPECT_EQ("CellularStateLinked",
Ben Chanf45b3232013-10-08 20:54:01 -0700493 Cellular::GetStateString(Cellular::kStateLinked));
494}
495
496TEST_F(CellularTest, GetModemStateString) {
Ben Chan7b7d63d2013-10-18 14:53:05 -0700497 EXPECT_EQ("CellularModemStateFailed",
498 Cellular::GetModemStateString(Cellular::kModemStateFailed));
Ben Chanf45b3232013-10-08 20:54:01 -0700499 EXPECT_EQ("CellularModemStateUnknown",
500 Cellular::GetModemStateString(Cellular::kModemStateUnknown));
501 EXPECT_EQ("CellularModemStateInitializing",
502 Cellular::GetModemStateString(Cellular::kModemStateInitializing));
503 EXPECT_EQ("CellularModemStateLocked",
504 Cellular::GetModemStateString(Cellular::kModemStateLocked));
505 EXPECT_EQ("CellularModemStateDisabled",
506 Cellular::GetModemStateString(Cellular::kModemStateDisabled));
507 EXPECT_EQ("CellularModemStateDisabling",
508 Cellular::GetModemStateString(Cellular::kModemStateDisabling));
509 EXPECT_EQ("CellularModemStateEnabling",
510 Cellular::GetModemStateString(Cellular::kModemStateEnabling));
511 EXPECT_EQ("CellularModemStateEnabled",
512 Cellular::GetModemStateString(Cellular::kModemStateEnabled));
513 EXPECT_EQ("CellularModemStateSearching",
514 Cellular::GetModemStateString(Cellular::kModemStateSearching));
515 EXPECT_EQ("CellularModemStateRegistered",
516 Cellular::GetModemStateString(Cellular::kModemStateRegistered));
517 EXPECT_EQ("CellularModemStateDisconnecting",
518 Cellular::GetModemStateString(Cellular::kModemStateDisconnecting));
519 EXPECT_EQ("CellularModemStateConnecting",
520 Cellular::GetModemStateString(Cellular::kModemStateConnecting));
521 EXPECT_EQ("CellularModemStateConnected",
522 Cellular::GetModemStateString(Cellular::kModemStateConnected));
Darin Petkove9d12e02011-07-27 15:09:37 -0700523}
524
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700525TEST_F(CellularTest, StartCDMARegister) {
Darin Petkov721ac932011-11-16 15:43:09 +0100526 SetCellularType(Cellular::kTypeCDMA);
Ben Chan7ea768e2013-09-20 15:08:40 -0700527 ExpectCdmaStartModem(kNetworkTechnology1Xrtt);
Darin Petkov975b5e72011-08-30 11:48:08 -0700528 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500529 Error error;
530 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
Darin Petkov0828f5f2011-08-11 10:18:52 -0700531 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400532 EXPECT_EQ(kMEID, GetCapabilityClassic()->meid_);
533 EXPECT_EQ(kTestCarrier, GetCapabilityClassic()->carrier_);
Darin Petkovbac96002011-08-09 13:22:00 -0700534 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovd2045802011-08-23 11:09:25 -0700535 ASSERT_TRUE(device_->service_.get());
Ben Chan7ea768e2013-09-20 15:08:40 -0700536 EXPECT_EQ(kNetworkTechnology1Xrtt, device_->service_->network_technology());
Darin Petkov22b72bf2011-08-29 14:01:20 -0700537 EXPECT_EQ(kStrength, device_->service_->strength());
Ben Chan7ea768e2013-09-20 15:08:40 -0700538 EXPECT_EQ(kRoamingStateHome, device_->service_->roaming_state());
Darin Petkovbac96002011-08-09 13:22:00 -0700539}
540
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700541TEST_F(CellularTest, StartGSMRegister) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700542 InitProviderDB();
Eric Shienbrood9a245532012-03-07 14:20:39 -0500543 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500544 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500545 EXPECT_CALL(*gsm_card_proxy_,
546 GetIMEI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500547 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMEI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500548 EXPECT_CALL(*gsm_card_proxy_,
549 GetIMSI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500550 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMSI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500551 EXPECT_CALL(*gsm_card_proxy_,
552 GetSPN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500553 .WillOnce(Invoke(this, &CellularTest::InvokeGetSPN));
554 EXPECT_CALL(*gsm_card_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500555 GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500556 .WillOnce(Invoke(this, &CellularTest::InvokeGetMSISDN));
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700557 EXPECT_CALL(*gsm_network_proxy_, AccessTechnology())
558 .WillOnce(Return(MM_MODEM_GSM_ACCESS_TECH_EDGE));
Darin Petkov63138a92012-02-06 14:09:15 +0100559 EXPECT_CALL(*gsm_card_proxy_, EnabledFacilityLocks())
560 .WillOnce(Return(MM_MODEM_GSM_FACILITY_SIM));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500561 EXPECT_CALL(*proxy_, GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500562 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Darin Petkov137884a2011-10-26 18:52:47 +0200563 static const char kNetworkID[] = "22803";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500564 EXPECT_CALL(*gsm_network_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500565 GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500566 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationInfo));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500567 EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality(NULL, _, _))
568 .Times(2)
569 .WillRepeatedly(Invoke(this,
570 &CellularTest::InvokeGetSignalQuality));
571 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700572 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Ben Chan3ecdf822012-08-06 12:29:23 -0700573 AllowCreateGSMCardProxyFromFactory();
574
Eric Shienbrood9a245532012-03-07 14:20:39 -0500575 Error error;
576 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
577 EXPECT_TRUE(error.IsSuccess());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700578 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400579 EXPECT_EQ(kIMEI, GetCapabilityGSM()->imei_);
580 EXPECT_EQ(kIMSI, GetCapabilityGSM()->imsi_);
Darin Petkova4ca3c32012-08-17 16:05:24 +0200581 EXPECT_EQ(kTestCarrierSPN, GetCapabilityGSM()->spn_);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400582 EXPECT_EQ(kMSISDN, GetCapabilityGSM()->mdn_);
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700583 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
584 ASSERT_TRUE(device_->service_.get());
Ben Chan7ea768e2013-09-20 15:08:40 -0700585 EXPECT_EQ(kNetworkTechnologyEdge, device_->service_->network_technology());
Darin Petkov63138a92012-02-06 14:09:15 +0100586 EXPECT_TRUE(GetCapabilityGSM()->sim_lock_status_.enabled);
Darin Petkov22b72bf2011-08-29 14:01:20 -0700587 EXPECT_EQ(kStrength, device_->service_->strength());
Ben Chan7ea768e2013-09-20 15:08:40 -0700588 EXPECT_EQ(kRoamingStateRoaming, device_->service_->roaming_state());
Darin Petkov137884a2011-10-26 18:52:47 +0200589 EXPECT_EQ(kNetworkID, device_->service_->serving_operator().GetCode());
Darin Petkova4ca3c32012-08-17 16:05:24 +0200590 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Darin Petkov137884a2011-10-26 18:52:47 +0200591 EXPECT_EQ("ch", device_->service_->serving_operator().GetCountry());
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700592}
593
Darin Petkovbac96002011-08-09 13:22:00 -0700594TEST_F(CellularTest, StartConnected) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700595 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
596 .WillOnce(Return(true));
Darin Petkov721ac932011-11-16 15:43:09 +0100597 SetCellularType(Cellular::kTypeCDMA);
Darin Petkovbac96002011-08-09 13:22:00 -0700598 device_->set_modem_state(Cellular::kModemStateConnected);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400599 GetCapabilityClassic()->meid_ = kMEID;
Ben Chan7ea768e2013-09-20 15:08:40 -0700600 ExpectCdmaStartModem(kNetworkTechnologyEvdo);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500601 Error error;
602 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
603 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700604 dispatcher_.DispatchPendingEvents();
Darin Petkovbac96002011-08-09 13:22:00 -0700605 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
606}
607
Darin Petkov0828f5f2011-08-11 10:18:52 -0700608TEST_F(CellularTest, StartLinked) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700609 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
610 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
Darin Petkov721ac932011-11-16 15:43:09 +0100611 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700612 device_->set_modem_state(Cellular::kModemStateConnected);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400613 GetCapabilityClassic()->meid_ = kMEID;
Ben Chan7ea768e2013-09-20 15:08:40 -0700614 ExpectCdmaStartModem(kNetworkTechnologyEvdo);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700615 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _))
Darin Petkov77cb6812011-08-15 16:19:41 -0700616 .WillOnce(Return(dhcp_config_));
617 EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700618 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_)).Times(3);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500619 Error error;
620 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
621 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700622 dispatcher_.DispatchPendingEvents();
623 EXPECT_EQ(Cellular::kStateLinked, device_->state_);
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700624 EXPECT_EQ(Service::kStateConfiguring, device_->service_->state());
625 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700626}
627
Darin Petkov3335b372011-08-22 11:05:32 -0700628TEST_F(CellularTest, CreateService) {
Darin Petkov721ac932011-11-16 15:43:09 +0100629 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov3335b372011-08-22 11:05:32 -0700630 static const char kPaymentURL[] = "https://payment.url";
631 static const char kUsageURL[] = "https://usage.url";
Darin Petkov3335b372011-08-22 11:05:32 -0700632 device_->home_provider_.SetName(kTestCarrier);
Darin Petkov381928f2012-02-02 23:00:12 +0100633 GetCapabilityCDMA()->olp_.SetURL(kPaymentURL);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100634 GetCapabilityCDMA()->usage_url_ = kUsageURL;
Darin Petkov3335b372011-08-22 11:05:32 -0700635 device_->CreateService();
636 ASSERT_TRUE(device_->service_.get());
Darin Petkov381928f2012-02-02 23:00:12 +0100637 EXPECT_EQ(kPaymentURL, device_->service_->olp().GetURL());
Darin Petkov3335b372011-08-22 11:05:32 -0700638 EXPECT_EQ(kUsageURL, device_->service_->usage_url());
639 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800640 ASSERT_FALSE(device_->service_->activate_over_non_cellular_network());
Darin Petkov3335b372011-08-22 11:05:32 -0700641}
642
Darin Petkovc5f56562011-08-06 16:40:05 -0700643namespace {
644
645MATCHER(ContainsPhoneNumber, "") {
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400646 return ContainsKey(arg,
647 CellularCapabilityClassic::kConnectPropertyPhoneNumber);
Darin Petkovc5f56562011-08-06 16:40:05 -0700648}
649
Eric Shienbrood9a245532012-03-07 14:20:39 -0500650} // namespace
Darin Petkovc5f56562011-08-06 16:40:05 -0700651
652TEST_F(CellularTest, Connect) {
Darin Petkov4d6d9412011-08-24 13:19:54 -0700653 Error error;
Chris Masone2ae797d2011-08-23 20:41:00 -0700654 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700655 .Times(2)
656 .WillRepeatedly(Return(true));
Darin Petkovc5f56562011-08-06 16:40:05 -0700657 device_->state_ = Cellular::kStateConnected;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700658 device_->Connect(&error);
659 EXPECT_EQ(Error::kAlreadyConnected, error.type());
660 error.Populate(Error::kSuccess);
Darin Petkovc5f56562011-08-06 16:40:05 -0700661
Darin Petkov0828f5f2011-08-11 10:18:52 -0700662 device_->state_ = Cellular::kStateLinked;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700663 device_->Connect(&error);
664 EXPECT_EQ(Error::kAlreadyConnected, error.type());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700665
Thieu Lec7d8cd12013-02-13 11:38:14 -0800666 device_->state_ = Cellular::kStateEnabled;
667 device_->Connect(&error);
668 EXPECT_EQ(Error::kNotRegistered, error.type());
669
670 error.Reset();
671 device_->state_ = Cellular::kStateDisabled;
672 device_->Connect(&error);
673 EXPECT_EQ(Error::kNotRegistered, error.type());
674
Darin Petkovc5f56562011-08-06 16:40:05 -0700675 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700676 SetService();
Darin Petkovd2045802011-08-23 11:09:25 -0700677
Jason Glasgow7b461df2012-05-01 16:38:45 -0400678 device_->allow_roaming_ = false;
Ben Chan7ea768e2013-09-20 15:08:40 -0700679 device_->service_->roaming_state_ = kRoamingStateRoaming;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700680 device_->Connect(&error);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700681 EXPECT_EQ(Error::kNotOnHomeNetwork, error.type());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500682
Darin Petkov4d6d9412011-08-24 13:19:54 -0700683 error.Populate(Error::kSuccess);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500684 EXPECT_CALL(*simple_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500685 Connect(ContainsPhoneNumber(), _, _,
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500686 CellularCapability::kTimeoutConnect))
687 .Times(2)
688 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400689 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Ben Chan7ea768e2013-09-20 15:08:40 -0700690 device_->service_->roaming_state_ = kRoamingStateHome;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500691 device_->state_ = Cellular::kStateRegistered;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700692 device_->Connect(&error);
693 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc5f56562011-08-06 16:40:05 -0700694 dispatcher_.DispatchPendingEvents();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500695 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
696
Jason Glasgow7b461df2012-05-01 16:38:45 -0400697 device_->allow_roaming_ = true;
Ben Chan7ea768e2013-09-20 15:08:40 -0700698 device_->service_->roaming_state_ = kRoamingStateRoaming;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500699 device_->state_ = Cellular::kStateRegistered;
700 device_->Connect(&error);
701 EXPECT_TRUE(error.IsSuccess());
702 dispatcher_.DispatchPendingEvents();
703 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
Darin Petkovc5f56562011-08-06 16:40:05 -0700704}
705
Eric Shienbrood9a245532012-03-07 14:20:39 -0500706TEST_F(CellularTest, Disconnect) {
707 Error error;
708 device_->state_ = Cellular::kStateRegistered;
709 device_->Disconnect(&error);
710 EXPECT_EQ(Error::kNotConnected, error.type());
711 error.Reset();
712
Darin Petkovfb0625e2012-01-16 13:05:56 +0100713 device_->state_ = Cellular::kStateConnected;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500714 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800715 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood9a245532012-03-07 14:20:39 -0500716 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400717 GetCapabilityClassic()->proxy_.reset(proxy_.release());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500718 device_->Disconnect(&error);
719 EXPECT_TRUE(error.IsSuccess());
720 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100721}
722
Arman Uguray539c4232012-09-11 10:00:22 -0700723TEST_F(CellularTest, DisconnectFailure) {
724 // Test the case where the underlying modem state is set
725 // to disconnecting, but shill thinks it's still connected
726 Error error;
727 device_->state_ = Cellular::kStateConnected;
728 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800729 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Arman Uguray539c4232012-09-11 10:00:22 -0700730 .Times(2)
731 .WillRepeatedly(Invoke(this, &CellularTest::InvokeDisconnectFail));
732 GetCapabilityClassic()->proxy_.reset(proxy_.release());
733 device_->modem_state_ = Cellular::kModemStateDisconnecting;
734 device_->Disconnect(&error);
735 EXPECT_TRUE(error.IsFailure());
736 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
737
738 device_->modem_state_ = Cellular::kModemStateConnected;
739 device_->Disconnect(&error);
740 EXPECT_TRUE(error.IsFailure());
741 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
742}
743
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400744TEST_F(CellularTest, ConnectFailure) {
745 SetCellularType(Cellular::kTypeCDMA);
746 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700747 SetService();
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400748 ASSERT_EQ(Service::kStateIdle, device_->service_->state());
749 EXPECT_CALL(*simple_proxy_,
750 Connect(_, _, _, CellularCapability::kTimeoutConnect))
751 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFail));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400752 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400753 Error error;
754 device_->Connect(&error);
755 EXPECT_EQ(Service::kStateFailure, device_->service_->state());
756}
757
Thieu Leb5954a22012-05-18 10:37:34 -0700758TEST_F(CellularTest, ConnectFailureNoService) {
759 // Make sure we don't crash if the connect failed and there is no
760 // CellularService object. This can happen if the modem is enabled and
761 // then quick disabled.
762 SetCellularType(Cellular::kTypeCDMA);
763 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700764 SetService();
Thieu Leb5954a22012-05-18 10:37:34 -0700765 EXPECT_CALL(
766 *simple_proxy_,
767 Connect(_, _, _, CellularCapability::kTimeoutConnect))
768 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFailNoService));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700769 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_));
Thieu Leb5954a22012-05-18 10:37:34 -0700770 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
771 Error error;
772 device_->Connect(&error);
773}
774
Thieu Led4974cd2013-05-23 10:39:28 -0700775TEST_F(CellularTest, ConnectSuccessNoService) {
776 // Make sure we don't crash if the connect succeeds but the service was
777 // destroyed before the connect request completes.
778 SetCellularType(Cellular::kTypeCDMA);
779 device_->state_ = Cellular::kStateRegistered;
780 SetService();
781 EXPECT_CALL(
782 *simple_proxy_,
783 Connect(_, _, _, CellularCapability::kTimeoutConnect))
784 .WillOnce(Invoke(this, &CellularTest::InvokeConnectSuccessNoService));
785 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_));
786 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
787 Error error;
788 device_->Connect(&error);
789}
790
Arman Uguray32c76402012-11-27 14:01:13 -0800791TEST_F(CellularTest, LinkEventWontDestroyService) {
792 // If the network interface goes down, Cellular::LinkEvent should
793 // drop the connection but the service object should persist.
794 device_->state_ = Cellular::kStateLinked;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700795 CellularService *service = SetService();
Arman Uguray32c76402012-11-27 14:01:13 -0800796 device_->LinkEvent(0, 0); // flags doesn't contain IFF_UP
797 EXPECT_EQ(device_->state_, Cellular::kStateConnected);
798 EXPECT_EQ(device_->service_, service);
799}
800
Arman Ugurayed8e6102012-11-29 14:47:20 -0800801TEST_F(CellularTest, UseNoArpGateway) {
802 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, false))
803 .WillOnce(Return(dhcp_config_));
804 device_->AcquireIPConfig();
805}
806
Ben Chan09fa2a02012-11-07 22:09:09 -0800807TEST_F(CellularTest, HandleNewRegistrationStateForServiceRequiringActivation) {
808 SetCellularType(Cellular::kTypeUniversal);
809
810 // Service activation is needed
811 GetCapabilityUniversal()->mdn_ = "0000000000";
Arman Ugurayf4c61812013-01-10 18:58:39 -0800812 CellularService::OLP olp;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700813 EXPECT_CALL(*modem_info_.mock_cellular_operator_info(), GetOLPByMCCMNC(_))
Arman Ugurayf4c61812013-01-10 18:58:39 -0800814 .WillRepeatedly(Return(&olp));
Arman Uguray41cc6342013-03-29 16:34:39 -0700815 EXPECT_CALL(*modem_info_.mock_pending_activation_store(),
816 GetActivationState(_,_))
817 .WillRepeatedly(Return(PendingActivationStore::kStateUnknown));
Ben Chan09fa2a02012-11-07 22:09:09 -0800818
819 device_->state_ = Cellular::kStateDisabled;
820 device_->HandleNewRegistrationState();
821 EXPECT_FALSE(device_->service_.get());
822
823 device_->state_ = Cellular::kStateEnabled;
824 device_->HandleNewRegistrationState();
825 EXPECT_TRUE(device_->service_.get());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800826 EXPECT_TRUE(device_->service_->activate_over_non_cellular_network());
Ben Chan09fa2a02012-11-07 22:09:09 -0800827}
828
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400829TEST_F(CellularTest, ModemStateChangeEnable) {
830 EXPECT_CALL(*simple_proxy_,
831 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
832 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
833 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
834 EXPECT_CALL(*proxy_,
835 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
836 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
837 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
838 .WillOnce(Invoke(this,
839 &CellularTest::InvokeGetRegistrationStateUnregistered));
840 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
841 .WillOnce(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700842 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400843 device_->state_ = Cellular::kStateDisabled;
844 device_->set_modem_state(Cellular::kModemStateDisabled);
845 SetCellularType(Cellular::kTypeCDMA);
846
847 DBusPropertiesMap props;
848 props[CellularCapabilityClassic::kModemPropertyEnabled].writer().
849 append_bool(true);
850 device_->OnDBusPropertiesChanged(MM_MODEM_INTERFACE, props, vector<string>());
851 dispatcher_.DispatchPendingEvents();
852
853 EXPECT_EQ(Cellular::kModemStateEnabled, device_->modem_state());
854 EXPECT_EQ(Cellular::kStateEnabled, device_->state());
855 EXPECT_TRUE(device_->enabled());
856}
857
858TEST_F(CellularTest, ModemStateChangeDisable) {
859 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800860 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400861 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
862 EXPECT_CALL(*proxy_,
Thieu Lec8d2d962012-05-15 14:31:18 -0700863 Enable(false, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400864 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700865 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400866 device_->enabled_ = true;
867 device_->enabled_pending_ = true;
868 device_->state_ = Cellular::kStateEnabled;
869 device_->set_modem_state(Cellular::kModemStateEnabled);
870 SetCellularType(Cellular::kTypeCDMA);
871 GetCapabilityClassic()->InitProxies();
872
873 GetCapabilityClassic()->OnModemStateChangedSignal(kModemClassicStateEnabled,
874 kModemClassicStateDisabled,
875 0);
876 dispatcher_.DispatchPendingEvents();
877
878 EXPECT_EQ(Cellular::kModemStateDisabled, device_->modem_state());
879 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
880 EXPECT_FALSE(device_->enabled());
881}
882
Thieu Led0012052012-07-25 16:09:09 -0700883TEST_F(CellularTest, ModemStateChangeStaleConnected) {
884 // Test to make sure that we ignore stale modem Connected state transitions.
885 // When a modem is asked to connect and before the connect completes, the
886 // modem is disabled, it may send a stale Connected state transition after
887 // it has been disabled.
888 device_->state_ = Cellular::kStateDisabled;
Arman Uguray1ee93912013-09-24 21:24:10 -0700889 device_->modem_state_ = Cellular::kModemStateEnabling;
890 device_->OnModemStateChanged(Cellular::kModemStateConnected);
Thieu Led0012052012-07-25 16:09:09 -0700891 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
892}
893
894TEST_F(CellularTest, ModemStateChangeValidConnected) {
895 device_->state_ = Cellular::kStateEnabled;
Arman Uguray1ee93912013-09-24 21:24:10 -0700896 device_->modem_state_ = Cellular::kModemStateConnecting;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700897 SetService();
Arman Uguray1ee93912013-09-24 21:24:10 -0700898 device_->OnModemStateChanged(Cellular::kModemStateConnected);
Thieu Led0012052012-07-25 16:09:09 -0700899 EXPECT_EQ(Cellular::kStateConnected, device_->state());
900}
901
Thieu Le5218cf22012-11-26 11:52:57 -0800902TEST_F(CellularTest, ModemStateChangeLostRegistration) {
903 SetCellularType(Cellular::kTypeUniversal);
904 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
905 capability->registration_state_ = MM_MODEM_3GPP_REGISTRATION_STATE_HOME;
906 EXPECT_TRUE(capability->IsRegistered());
Arman Uguray1ee93912013-09-24 21:24:10 -0700907 device_->set_modem_state(Cellular::kModemStateRegistered);
908 device_->OnModemStateChanged(Cellular::kModemStateEnabled);
Thieu Le5218cf22012-11-26 11:52:57 -0800909 EXPECT_FALSE(capability->IsRegistered());
910}
911
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700912TEST_F(CellularTest, EnableTrafficMonitor) {
913 SetCellularType(Cellular::kTypeUniversal);
914 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
915 capability->model_id_.clear();
916 EXPECT_CALL(*this, TestCallback(IsSuccess()));
917 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
918 Unretained(this)),
919 Error(Error::kSuccess));
920 EXPECT_FALSE(device_->traffic_monitor_enabled());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700921 Mock::VerifyAndClearExpectations(this);
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700922
923 device_->state_ = Cellular::kStateDisabled;
924
Ben Chan4ffc03b2013-08-07 17:44:53 -0700925 capability->model_id_ = CellularCapabilityUniversal::kALT3100ModelId;
926 EXPECT_CALL(*this, TestCallback(IsFailure()));
927 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
928 Unretained(this)),
929 Error(Error::kOperationFailed));
930 EXPECT_FALSE(device_->traffic_monitor_enabled());
931 Mock::VerifyAndClearExpectations(this);
932
933 EXPECT_CALL(*this, TestCallback(IsSuccess()));
934 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
935 Unretained(this)),
936 Error(Error::kSuccess));
937 EXPECT_TRUE(device_->traffic_monitor_enabled());
938 Mock::VerifyAndClearExpectations(this);
939
940 device_->state_ = Cellular::kStateDisabled;
941 device_->traffic_monitor_enabled_ = false;
942
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700943 capability->model_id_ = CellularCapabilityUniversal::kE362ModelId;
944 EXPECT_CALL(*this, TestCallback(IsFailure()));
945 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
946 Unretained(this)),
947 Error(Error::kOperationFailed));
948 EXPECT_FALSE(device_->traffic_monitor_enabled());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700949 Mock::VerifyAndClearExpectations(this);
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700950
951 EXPECT_CALL(*this, TestCallback(IsSuccess()));
952 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
953 Unretained(this)),
954 Error(Error::kSuccess));
955 EXPECT_TRUE(device_->traffic_monitor_enabled());
956}
957
Thieu Le37b90032012-05-15 15:18:41 -0700958TEST_F(CellularTest, StartModemCallback) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700959 EXPECT_CALL(*this, TestCallback(IsSuccess()));
960 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700961 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
962 Unretained(this)),
963 Error(Error::kSuccess));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700964 EXPECT_EQ(device_->state_, Cellular::kStateEnabled);
965}
966
Thieu Le37b90032012-05-15 15:18:41 -0700967TEST_F(CellularTest, StartModemCallbackFail) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700968 EXPECT_CALL(*this, TestCallback(IsFailure()));
969 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700970 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
971 Unretained(this)),
972 Error(Error::kOperationFailed));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700973 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
974}
975
Thieu Le37b90032012-05-15 15:18:41 -0700976TEST_F(CellularTest, StopModemCallback) {
977 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700978 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -0700979 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
980 Unretained(this)),
981 Error(Error::kSuccess));
982 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
983 EXPECT_FALSE(device_->service_.get());
984}
985
986TEST_F(CellularTest, StopModemCallbackFail) {
987 EXPECT_CALL(*this, TestCallback(IsFailure()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700988 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -0700989 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
990 Unretained(this)),
991 Error(Error::kOperationFailed));
992 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
993 EXPECT_FALSE(device_->service_.get());
994}
995
Arman Ugurayf84a4242013-04-09 20:01:07 -0700996TEST_F(CellularTest, OnConnectionHealthCheckerResult) {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700997 MockCellularService *service(SetMockService());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700998 EXPECT_FALSE(service->out_of_credits_);
999
1000 EXPECT_CALL(*service, Disconnect(_)).Times(0);
1001 device_->OnConnectionHealthCheckerResult(
1002 ConnectionHealthChecker::kResultUnknown);
1003 EXPECT_FALSE(service->out_of_credits_);
1004 device_->OnConnectionHealthCheckerResult(
Arman Ugurayf84a4242013-04-09 20:01:07 -07001005 ConnectionHealthChecker::kResultConnectionFailure);
1006 EXPECT_FALSE(service->out_of_credits_);
1007 Mock::VerifyAndClearExpectations(service);
1008
1009 EXPECT_CALL(*service, Disconnect(_)).Times(1);
1010 device_->OnConnectionHealthCheckerResult(
Arman Ugurayf84a4242013-04-09 20:01:07 -07001011 ConnectionHealthChecker::kResultCongestedTxQueue);
1012 EXPECT_TRUE(service->out_of_credits_);
Arman Ugurayf84a4242013-04-09 20:01:07 -07001013}
1014
Darin Petkove7c6ad32012-06-29 10:22:09 +02001015TEST_F(CellularTest, SetAllowRoaming) {
1016 EXPECT_FALSE(device_->allow_roaming_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -07001017 EXPECT_CALL(*modem_info_.mock_manager(), UpdateDevice(_));
Darin Petkove7c6ad32012-06-29 10:22:09 +02001018 Error error;
1019 device_->SetAllowRoaming(true, &error);
1020 EXPECT_TRUE(error.IsSuccess());
1021 EXPECT_TRUE(device_->allow_roaming_);
1022}
1023
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001024class TestRPCTaskDelegate :
1025 public RPCTaskDelegate,
1026 public base::SupportsWeakPtr<TestRPCTaskDelegate> {
1027 public:
1028 virtual void GetLogin(std::string *user, std::string *password) {}
1029 virtual void Notify(const std::string &reason,
1030 const std::map<std::string, std::string> &dict) {}
1031};
1032
1033TEST_F(CellularTest, LinkEventUpWithPPP) {
1034 // If PPP is running, don't run DHCP as well.
1035 TestRPCTaskDelegate task_delegate;
1036 base::Callback<void(pid_t, int)> death_callback;
1037 scoped_ptr<NiceMock<MockExternalTask>> mock_task(
1038 new NiceMock<MockExternalTask>(modem_info_.control_interface(),
1039 modem_info_.glib(),
1040 task_delegate.AsWeakPtr(),
1041 death_callback));
1042 EXPECT_CALL(*mock_task, OnDelete()).Times(AnyNumber());
1043 device_->ppp_task_ = mock_task.Pass();
1044 device_->state_ = Cellular::kStateConnected;
1045 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _))
1046 .Times(0);
1047 EXPECT_CALL(*dhcp_config_, RequestIP()).Times(0);
1048 device_->LinkEvent(IFF_UP, 0);
1049}
1050
1051TEST_F(CellularTest, LinkEventUpWithoutPPP) {
1052 // If PPP is not running, fire up DHCP.
1053 device_->state_ = Cellular::kStateConnected;
1054 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _))
1055 .WillOnce(Return(dhcp_config_));
1056 EXPECT_CALL(*dhcp_config_, RequestIP());
1057 EXPECT_CALL(*dhcp_config_, ReleaseIP(_)).Times(AnyNumber());
1058 device_->LinkEvent(IFF_UP, 0);
1059}
1060
mukesh agrawalf407d592013-07-31 11:37:57 -07001061TEST_F(CellularTest, StartPPP) {
1062 const int kPID = 234;
1063 EXPECT_FALSE(device_->ppp_task_);
1064 StartPPP(kPID);
1065}
1066
1067TEST_F(CellularTest, StartPPPAlreadyStarted) {
1068 const int kPID = 234;
1069 StartPPP(kPID);
1070
1071 const int kPID2 = 235;
1072 StartPPP(kPID2);
1073}
1074
mukesh agrawal35ec8402013-07-19 14:49:08 -07001075TEST_F(CellularTest, StartPPPAfterEthernetUp) {
1076 CellularService *service(SetService());
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001077 device_->state_ = Cellular::kStateLinked;
mukesh agrawal35ec8402013-07-19 14:49:08 -07001078 device_->set_ipconfig(dhcp_config_);
1079 device_->SelectService(service);
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001080 EXPECT_CALL(*dhcp_config_, ReleaseIP(_))
1081 .Times(AnyNumber())
1082 .WillRepeatedly(Return(true));
mukesh agrawalf407d592013-07-31 11:37:57 -07001083 const int kPID = 234;
1084 EXPECT_FALSE(device_->ppp_task_);
1085 StartPPP(kPID);
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001086 EXPECT_EQ(Cellular::kStateLinked, device_->state());
mukesh agrawalfbc40d22013-06-28 00:25:13 -07001087}
1088
mukesh agrawal3ffe52c2013-06-20 15:21:29 -07001089TEST_F(CellularTest, GetLogin) {
1090 // Doesn't crash when there is no service.
1091 string username_to_pppd;
1092 string password_to_pppd;
1093 EXPECT_FALSE(device_->service());
1094 device_->GetLogin(&username_to_pppd, &password_to_pppd);
1095
1096 // Provides expected username and password in normal case.
1097 const char kFakeUsername[] = "fake-user";
1098 const char kFakePassword[] = "fake-password";
1099 CellularService &service(*SetService());
1100 service.ppp_username_ = kFakeUsername;
1101 service.ppp_password_ = kFakePassword;
1102 device_->GetLogin(&username_to_pppd, &password_to_pppd);
1103}
1104
mukesh agrawalf407d592013-07-31 11:37:57 -07001105TEST_F(CellularTest, Notify) {
1106 // Common setup.
1107 MockPPPDeviceFactory *ppp_device_factory =
1108 MockPPPDeviceFactory::GetInstance();
mukesh agrawalfc362912013-08-06 18:10:07 -07001109 const int kPID = 91;
mukesh agrawalf407d592013-07-31 11:37:57 -07001110 device_->ppp_device_factory_ = ppp_device_factory;
1111 SetMockService();
mukesh agrawalfc362912013-08-06 18:10:07 -07001112 StartPPP(kPID);
1113
1114 const map<string, string> kEmptyArgs;
1115 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1116 EXPECT_TRUE(device_->is_ppp_authenticating_);
1117 device_->Notify(kPPPReasonAuthenticated, kEmptyArgs);
1118 EXPECT_FALSE(device_->is_ppp_authenticating_);
mukesh agrawalf407d592013-07-31 11:37:57 -07001119
1120 // Normal connect.
1121 const string kInterfaceName("fake-device");
1122 const int kInterfaceIndex = 1;
1123 scoped_refptr<MockPPPDevice> ppp_device;
1124 map<string, string> ppp_config;
1125 ppp_device =
1126 new MockPPPDevice(modem_info_.control_interface(),
1127 NULL, NULL, NULL, kInterfaceName, kInterfaceIndex);
1128 ppp_config[kPPPInterfaceName] = kInterfaceName;
1129 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
1130 .WillOnce(Return(kInterfaceIndex));
1131 EXPECT_CALL(device_info_, RegisterDevice(_));
1132 EXPECT_CALL(*ppp_device_factory,
1133 CreatePPPDevice(_, _, _, _, kInterfaceName, kInterfaceIndex))
1134 .WillOnce(Return(ppp_device));
1135 EXPECT_CALL(*ppp_device, SetEnabled(true));
1136 EXPECT_CALL(*ppp_device, SelectService(_));
1137 EXPECT_CALL(*ppp_device, UpdateIPConfigFromPPP(ppp_config, false));
1138 device_->Notify(kPPPReasonConnect, ppp_config);
1139 Mock::VerifyAndClearExpectations(&device_info_);
1140 Mock::VerifyAndClearExpectations(ppp_device);
1141
1142 // Re-connect on same network device: if pppd sends us multiple connect
1143 // events, we behave sanely.
1144 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
1145 .WillOnce(Return(kInterfaceIndex));
1146 EXPECT_CALL(*ppp_device, SetEnabled(true));
1147 EXPECT_CALL(*ppp_device, SelectService(_));
1148 EXPECT_CALL(*ppp_device, UpdateIPConfigFromPPP(ppp_config, false));
1149 device_->Notify(kPPPReasonConnect, ppp_config);
1150 Mock::VerifyAndClearExpectations(&device_info_);
1151 Mock::VerifyAndClearExpectations(ppp_device);
1152
1153 // Re-connect on new network device: if we still have the PPPDevice
1154 // from a prior connect, this new connect should DTRT. This is
1155 // probably an unlikely case.
1156 const string kInterfaceName2("fake-device2");
1157 const int kInterfaceIndex2 = 2;
1158 scoped_refptr<MockPPPDevice> ppp_device2;
1159 map<string, string> ppp_config2;
1160 ppp_device2 =
1161 new MockPPPDevice(modem_info_.control_interface(),
1162 NULL, NULL, NULL, kInterfaceName2, kInterfaceIndex2);
1163 ppp_config2[kPPPInterfaceName] = kInterfaceName2;
1164 EXPECT_CALL(device_info_, GetIndex(kInterfaceName2))
1165 .WillOnce(Return(kInterfaceIndex2));
1166 EXPECT_CALL(device_info_,
1167 RegisterDevice(static_cast<DeviceRefPtr>(ppp_device2)));
1168 EXPECT_CALL(*ppp_device_factory,
1169 CreatePPPDevice(_, _, _, _, kInterfaceName2, kInterfaceIndex2))
1170 .WillOnce(Return(ppp_device2));
1171 EXPECT_CALL(*ppp_device, SelectService(ServiceRefPtr(nullptr)));
1172 EXPECT_CALL(*ppp_device2, SetEnabled(true));
1173 EXPECT_CALL(*ppp_device2, SelectService(_));
1174 EXPECT_CALL(*ppp_device2, UpdateIPConfigFromPPP(ppp_config2, false));
1175 device_->Notify(kPPPReasonConnect, ppp_config2);
1176 Mock::VerifyAndClearExpectations(&device_info_);
mukesh agrawalfc362912013-08-06 18:10:07 -07001177 Mock::VerifyAndClearExpectations(ppp_device);
mukesh agrawalf407d592013-07-31 11:37:57 -07001178 Mock::VerifyAndClearExpectations(ppp_device2);
1179
mukesh agrawalfc362912013-08-06 18:10:07 -07001180 // Disconnect should report unknown failure, since we had a
1181 // Notify(kPPPReasonAuthenticated, ...).
1182 EXPECT_CALL(*ppp_device2, SetServiceFailure(Service::kFailureUnknown));
1183 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1184 EXPECT_FALSE(device_->ppp_task_);
1185}
1186
1187TEST_F(CellularTest, PPPConnectionFailedBeforeAuth) {
1188 // Test that we properly set Service state in the case where pppd
1189 // disconnects before authenticating (as opposed to the Notify test,
1190 // where pppd disconnects after connecting).
1191 const int kPID = 52;
1192 const map<string, string> kEmptyArgs;
1193 MockCellularService *service = SetMockService();
1194 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001195
1196 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001197 EXPECT_CALL(*service, SetFailure(Service::kFailureUnknown));
1198 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1199 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001200 VerifyDisconnect();
mukesh agrawalfc362912013-08-06 18:10:07 -07001201}
1202
1203TEST_F(CellularTest, PPPConnectionFailedDuringAuth) {
1204 // Test that we properly set Service state in the case where pppd
1205 // disconnects during authentication (as opposed to the Notify test,
1206 // where pppd disconnects after connecting).
1207 const int kPID = 52;
1208 const map<string, string> kEmptyArgs;
1209 MockCellularService *service = SetMockService();
1210 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001211
1212 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001213 EXPECT_CALL(*service, SetFailure(Service::kFailurePPPAuth));
1214 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1215 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
1216 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001217 VerifyDisconnect();
mukesh agrawalfc362912013-08-06 18:10:07 -07001218}
1219
1220TEST_F(CellularTest, PPPConnectionFailedAfterAuth) {
1221 // Test that we properly set Service state in the case where pppd
1222 // disconnects after authenticating, but before connecting (as
1223 // opposed to the Notify test, where pppd disconnects after
1224 // connecting).
1225 const int kPID = 52;
1226 const map<string, string> kEmptyArgs;
1227 MockCellularService *service = SetMockService();
1228 StartPPP(kPID);
mukesh agrawalee10f372013-08-14 14:07:11 -07001229
mukesh agrawalfc362912013-08-06 18:10:07 -07001230 EXPECT_CALL(*service, SetFailure(Service::kFailureUnknown));
mukesh agrawalee10f372013-08-14 14:07:11 -07001231 ExpectDisconnectCapabilityUniversal();
mukesh agrawalfc362912013-08-06 18:10:07 -07001232 device_->Notify(kPPPReasonAuthenticating, kEmptyArgs);
1233 device_->Notify(kPPPReasonAuthenticated, kEmptyArgs);
1234 device_->Notify(kPPPReasonDisconnect, kEmptyArgs);
mukesh agrawalf407d592013-07-31 11:37:57 -07001235 EXPECT_FALSE(device_->ppp_task_);
mukesh agrawalee10f372013-08-14 14:07:11 -07001236 VerifyDisconnect();
mukesh agrawalf407d592013-07-31 11:37:57 -07001237}
1238
1239TEST_F(CellularTest, OnPPPDied) {
1240 const int kPID = 1234;
1241 const int kExitStatus = 5;
mukesh agrawalee10f372013-08-14 14:07:11 -07001242 ExpectDisconnectCapabilityUniversal();
mukesh agrawalf407d592013-07-31 11:37:57 -07001243 device_->OnPPPDied(kPID, kExitStatus);
mukesh agrawalee10f372013-08-14 14:07:11 -07001244 VerifyDisconnect();
mukesh agrawalf407d592013-07-31 11:37:57 -07001245}
1246
mukesh agrawal5d851b12013-07-11 14:09:41 -07001247TEST_F(CellularTest, DropConnection) {
1248 device_->set_ipconfig(dhcp_config_);
1249 EXPECT_CALL(*dhcp_config_, ReleaseIP(_));
1250 device_->DropConnection();
1251 Mock::VerifyAndClearExpectations(dhcp_config_); // verify before dtor
1252 EXPECT_FALSE(device_->ipconfig());
1253}
1254
1255TEST_F(CellularTest, DropConnectionPPP) {
1256 scoped_refptr<MockPPPDevice> ppp_device(
1257 new MockPPPDevice(modem_info_.control_interface(),
1258 NULL, NULL, NULL, "fake_ppp0", -1));
1259 EXPECT_CALL(*ppp_device, DropConnection());
1260 device_->ppp_device_ = ppp_device;
1261 device_->DropConnection();
1262}
1263
mukesh agrawal0381f9a2013-07-11 16:41:52 -07001264TEST_F(CellularTest, ChangeServiceState) {
1265 MockCellularService *service(SetMockService());
1266 EXPECT_CALL(*service, SetState(_));
1267 EXPECT_CALL(*service, SetFailure(_));
1268 EXPECT_CALL(*service, SetFailureSilent(_));
1269
1270 // Without PPP, these should be handled by our selected_service().
1271 device_->SelectService(service);
1272 device_->SetServiceState(Service::kStateConfiguring);
1273 device_->SetServiceFailure(Service::kFailurePPPAuth);
1274 device_->SetServiceFailureSilent(Service::kFailureUnknown);
1275 Mock::VerifyAndClearExpectations(service); // before Cellular dtor
1276}
1277
1278TEST_F(CellularTest, ChangeServiceStatePPP) {
1279 MockCellularService *service(SetMockService());
1280 scoped_refptr<MockPPPDevice> ppp_device(
1281 new MockPPPDevice(modem_info_.control_interface(),
1282 NULL, NULL, NULL, "fake_ppp0", -1));
1283 EXPECT_CALL(*ppp_device, SetServiceState(_));
1284 EXPECT_CALL(*ppp_device, SetServiceFailure(_));
1285 EXPECT_CALL(*ppp_device, SetServiceFailureSilent(_));
1286 EXPECT_CALL(*service, SetState(_)).Times(0);
1287 EXPECT_CALL(*service, SetFailure(_)).Times(0);
1288 EXPECT_CALL(*service, SetFailureSilent(_)).Times(0);
1289 device_->ppp_device_ = ppp_device;
1290
1291 // With PPP, these should all be punted over to the |ppp_device|.
1292 // Note in particular that Cellular does not manipulate |service| in
1293 // this case.
1294 device_->SetServiceState(Service::kStateConfiguring);
1295 device_->SetServiceFailure(Service::kFailurePPPAuth);
1296 device_->SetServiceFailureSilent(Service::kFailureUnknown);
1297}
1298
mukesh agrawal5c8ed242013-10-04 11:59:58 -07001299TEST_F(CellularTest, StopPPPOnDisconnect) {
1300 const int kPID = 123;
1301 StartPPP(kPID);
1302
1303 const char kInterfaceName[] = "fake-ppp-device";
1304 const int kInterfaceIndex = -1;
1305 auto mock_ppp_device = make_scoped_refptr(new MockPPPDevice(
1306 modem_info_.control_interface(), NULL, NULL, NULL, kInterfaceName,
1307 kInterfaceIndex));
1308 device_->ppp_device_ = mock_ppp_device;
1309 device_->state_ = Cellular::kStateConnected;
1310
1311 Error error;
1312 EXPECT_CALL(*mock_ppp_device, DropConnection());
1313 device_->Disconnect(&error);
1314 EXPECT_FALSE(device_->ppp_task_);
1315 EXPECT_FALSE(device_->ppp_device_);
1316}
1317
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001318// Custom property setters should return false, and make no changes, if
1319// the new value is the same as the old value.
1320TEST_F(CellularTest, CustomSetterNoopChange) {
1321 Error error;
1322 EXPECT_FALSE(device_->allow_roaming_);
1323 EXPECT_FALSE(device_->SetAllowRoaming(false, &error));
1324 EXPECT_TRUE(error.IsSuccess());
1325}
1326
Chris Masoneb925cc82011-06-22 15:39:57 -07001327} // namespace shill