1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/cellular/cellular_capability_gsm.h"
18
19 #include <base/bind.h>
20 #if defined(__ANDROID__)
21 #include <dbus/service_constants.h>
22 #else
23 #include <chromeos/dbus/service_constants.h>
24 #endif // __ANDROID__
25 #include <mm/mm-modem.h>
26
27 #include "shill/cellular/cellular.h"
28 #include "shill/cellular/cellular_service.h"
29 #include "shill/cellular/mock_modem_cdma_proxy.h"
30 #include "shill/cellular/mock_modem_gobi_proxy.h"
31 #include "shill/cellular/mock_modem_gsm_card_proxy.h"
32 #include "shill/cellular/mock_modem_gsm_network_proxy.h"
33 #include "shill/cellular/mock_modem_info.h"
34 #include "shill/cellular/mock_modem_proxy.h"
35 #include "shill/cellular/mock_modem_simple_proxy.h"
36 #include "shill/error.h"
37 #include "shill/mock_adaptors.h"
38 #include "shill/mock_control.h"
39 #include "shill/mock_profile.h"
40 #include "shill/net/mock_rtnl_handler.h"
41 #include "shill/test_event_dispatcher.h"
42 #include "shill/testing.h"
43
44 using base::Bind;
45 using base::Unretained;
46 using std::string;
47 using testing::InSequence;
48 using testing::NiceMock;
49 using testing::_;
50
51 namespace shill {
52
53 class CellularCapabilityTest : public testing::Test {
54 public:
CellularCapabilityTest()55 CellularCapabilityTest()
56 : control_interface_(this),
57 modem_info_(&control_interface_, &dispatcher_, nullptr, nullptr),
58 create_gsm_card_proxy_from_factory_(false),
59 proxy_(new MockModemProxy()),
60 simple_proxy_(new MockModemSimpleProxy()),
61 cdma_proxy_(new MockModemCDMAProxy()),
62 gsm_card_proxy_(new MockModemGSMCardProxy()),
63 gsm_network_proxy_(new MockModemGSMNetworkProxy()),
64 gobi_proxy_(new MockModemGobiProxy()),
65 capability_(nullptr),
66 device_adaptor_(nullptr),
67 cellular_(new Cellular(&modem_info_,
68 "",
69 "",
70 0,
71 Cellular::kTypeGSM,
72 "",
73 "")) {
74 modem_info_.metrics()->RegisterDevice(cellular_->interface_index(),
75 Technology::kCellular);
76 }
77
~CellularCapabilityTest()78 virtual ~CellularCapabilityTest() {
79 cellular_->service_ = nullptr;
80 capability_ = nullptr;
81 device_adaptor_ = nullptr;
82 }
83
SetUp()84 virtual void SetUp() {
85 static_cast<Device*>(cellular_.get())->rtnl_handler_ = &rtnl_handler_;
86
87 capability_ = static_cast<CellularCapabilityClassic*>(
88 cellular_->capability_.get());
89 device_adaptor_ =
90 static_cast<DeviceMockAdaptor*>(cellular_->adaptor());
91 ASSERT_NE(nullptr, device_adaptor_);;
92 }
93
TearDown()94 virtual void TearDown() {
95 capability_->control_interface_ = nullptr;
96 }
97
CreateService()98 void CreateService() {
99 // The following constants are never directly accessed by the tests.
100 const char kStorageIdentifier[] = "default_test_storage_id";
101 const char kFriendlyServiceName[] = "default_test_service_name";
102 const char kOperatorCode[] = "10010";
103 const char kOperatorName[] = "default_test_operator_name";
104 const char kOperatorCountry[] = "us";
105
106 // Simulate all the side-effects of Cellular::CreateService
107 auto service = new CellularService(&modem_info_, cellular_);
108 service->SetStorageIdentifier(kStorageIdentifier);
109 service->SetFriendlyName(kFriendlyServiceName);
110
111 Stringmap serving_operator;
112 serving_operator[kOperatorCodeKey] = kOperatorCode;
113 serving_operator[kOperatorNameKey] = kOperatorName;
114 serving_operator[kOperatorCountryKey] = kOperatorCountry;
115
116 service->set_serving_operator(serving_operator);
117 cellular_->set_home_provider(serving_operator);
118 cellular_->service_ = service;
119 }
120
GetGsmCapability()121 CellularCapabilityGSM* GetGsmCapability() {
122 return static_cast<CellularCapabilityGSM*>(cellular_->capability_.get());
123 }
124
ReleaseCapabilityProxies()125 void ReleaseCapabilityProxies() {
126 capability_->ReleaseProxies();
127 }
128
InvokeEnable(bool enable,Error * error,const ResultCallback & callback,int timeout)129 void InvokeEnable(bool enable, Error* error,
130 const ResultCallback& callback, int timeout) {
131 callback.Run(Error());
132 }
InvokeEnableFail(bool enable,Error * error,const ResultCallback & callback,int timeout)133 void InvokeEnableFail(bool enable, Error* error,
134 const ResultCallback& callback, int timeout) {
135 callback.Run(Error(Error::kOperationFailed));
136 }
InvokeDisconnect(Error * error,const ResultCallback & callback,int timeout)137 void InvokeDisconnect(Error* error, const ResultCallback& callback,
138 int timeout) {
139 callback.Run(Error());
140 }
InvokeDisconnectFail(Error * error,const ResultCallback & callback,int timeout)141 void InvokeDisconnectFail(Error* error, const ResultCallback& callback,
142 int timeout) {
143 callback.Run(Error(Error::kOperationFailed));
144 }
InvokeGetModemStatus(Error * error,const KeyValueStoreCallback & callback,int timeout)145 void InvokeGetModemStatus(Error* error,
146 const KeyValueStoreCallback& callback,
147 int timeout) {
148 KeyValueStore props;
149 props.SetString("carrier", kTestCarrier);
150 props.SetString("unknown-property", "irrelevant-value");
151 callback.Run(props, Error());
152 }
InvokeGetModemInfo(Error * error,const ModemInfoCallback & callback,int timeout)153 void InvokeGetModemInfo(Error* error, const ModemInfoCallback& callback,
154 int timeout) {
155 callback.Run(kManufacturer, kModelID, kHWRev, Error());
156 }
InvokeSetCarrier(const string & carrier,Error * error,const ResultCallback & callback,int timeout)157 void InvokeSetCarrier(const string& carrier, Error* error,
158 const ResultCallback& callback, int timeout) {
159 callback.Run(Error());
160 }
161
162 MOCK_METHOD1(TestCallback, void(const Error& error));
163
164 protected:
165 static const char kTestMobileProviderDBPath[];
166 static const char kTestCarrier[];
167 static const char kManufacturer[];
168 static const char kModelID[];
169 static const char kHWRev[];
170
171 class TestControl : public MockControl {
172 public:
TestControl(CellularCapabilityTest * test)173 explicit TestControl(CellularCapabilityTest* test) : test_(test) {}
174
CreateModemProxy(const string &,const string &)175 virtual ModemProxyInterface* CreateModemProxy(
176 const string& /*path*/,
177 const string& /*service*/) {
178 return test_->proxy_.release();
179 }
180
CreateModemSimpleProxy(const string &,const string &)181 virtual ModemSimpleProxyInterface* CreateModemSimpleProxy(
182 const string& /*path*/,
183 const string& /*service*/) {
184 return test_->simple_proxy_.release();
185 }
186
CreateModemCDMAProxy(const string &,const string &)187 virtual ModemCDMAProxyInterface* CreateModemCDMAProxy(
188 const string& /*path*/,
189 const string& /*service*/) {
190 return test_->cdma_proxy_.release();
191 }
192
CreateModemGSMCardProxy(const string &,const string &)193 virtual ModemGSMCardProxyInterface* CreateModemGSMCardProxy(
194 const string& /*path*/,
195 const string& /*service*/) {
196 // TODO(benchan): This code conditionally returns a nullptr to avoid
197 // CellularCapabilityGSM::InitProperties (and thus
198 // CellularCapabilityGSM::GetIMSI) from being called during the
199 // construction. Remove this workaround after refactoring the tests.
200 return test_->create_gsm_card_proxy_from_factory_ ?
201 test_->gsm_card_proxy_.release() : nullptr;
202 }
203
CreateModemGSMNetworkProxy(const string &,const string &)204 virtual ModemGSMNetworkProxyInterface* CreateModemGSMNetworkProxy(
205 const string& /*path*/,
206 const string& /*service*/) {
207 return test_->gsm_network_proxy_.release();
208 }
209
CreateModemGobiProxy(const string &,const string &)210 virtual ModemGobiProxyInterface* CreateModemGobiProxy(
211 const string& /*path*/,
212 const string& /*service*/) {
213 return test_->gobi_proxy_.release();
214 }
215
216 private:
217 CellularCapabilityTest* test_;
218 };
219
SetProxy()220 void SetProxy() {
221 capability_->proxy_.reset(proxy_.release());
222 }
223
SetSimpleProxy()224 void SetSimpleProxy() {
225 capability_->simple_proxy_.reset(simple_proxy_.release());
226 }
227
SetGSMNetworkProxy()228 void SetGSMNetworkProxy() {
229 CellularCapabilityGSM* gsm_capability =
230 static_cast<CellularCapabilityGSM*>(cellular_->capability_.get());
231 gsm_capability->network_proxy_.reset(gsm_network_proxy_.release());
232 }
233
SetCellularType(Cellular::Type type)234 void SetCellularType(Cellular::Type type) {
235 cellular_->InitCapability(type);
236 capability_ = static_cast<CellularCapabilityClassic*>(
237 cellular_->capability_.get());
238 }
239
AllowCreateGSMCardProxyFromFactory()240 void AllowCreateGSMCardProxyFromFactory() {
241 create_gsm_card_proxy_from_factory_ = true;
242 }
243
244 EventDispatcherForTest dispatcher_;
245 TestControl control_interface_;
246 MockModemInfo modem_info_;
247 MockRTNLHandler rtnl_handler_;
248 bool create_gsm_card_proxy_from_factory_;
249 std::unique_ptr<MockModemProxy> proxy_;
250 std::unique_ptr<MockModemSimpleProxy> simple_proxy_;
251 std::unique_ptr<MockModemCDMAProxy> cdma_proxy_;
252 std::unique_ptr<MockModemGSMCardProxy> gsm_card_proxy_;
253 std::unique_ptr<MockModemGSMNetworkProxy> gsm_network_proxy_;
254 std::unique_ptr<MockModemGobiProxy> gobi_proxy_;
255 CellularCapabilityClassic* capability_; // Owned by |cellular_|.
256 DeviceMockAdaptor* device_adaptor_; // Owned by |cellular_|.
257 CellularRefPtr cellular_;
258 };
259
260 const char CellularCapabilityTest::kTestMobileProviderDBPath[] =
261 "provider_db_unittest.bfd";
262 const char CellularCapabilityTest::kTestCarrier[] = "The Cellular Carrier";
263 const char CellularCapabilityTest::kManufacturer[] = "Company";
264 const char CellularCapabilityTest::kModelID[] = "Gobi 2000";
265 const char CellularCapabilityTest::kHWRev[] = "A00B1234";
266
TEST_F(CellularCapabilityTest,GetModemStatus)267 TEST_F(CellularCapabilityTest, GetModemStatus) {
268 SetCellularType(Cellular::kTypeCDMA);
269 EXPECT_CALL(*simple_proxy_,
270 GetModemStatus(_, _, CellularCapability::kTimeoutDefault)).
271 WillOnce(Invoke(this, &CellularCapabilityTest::InvokeGetModemStatus));
272 EXPECT_CALL(*this, TestCallback(IsSuccess()));
273 SetSimpleProxy();
274 ResultCallback callback =
275 Bind(&CellularCapabilityTest::TestCallback, Unretained(this));
276 capability_->GetModemStatus(callback);
277 EXPECT_EQ(kTestCarrier, cellular_->carrier());
278 }
279
TEST_F(CellularCapabilityTest,GetModemInfo)280 TEST_F(CellularCapabilityTest, GetModemInfo) {
281 EXPECT_CALL(*proxy_, GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
282 .WillOnce(Invoke(this, &CellularCapabilityTest::InvokeGetModemInfo));
283 EXPECT_CALL(*this, TestCallback(IsSuccess()));
284 SetProxy();
285 ResultCallback callback =
286 Bind(&CellularCapabilityTest::TestCallback, Unretained(this));
287 capability_->GetModemInfo(callback);
288 EXPECT_EQ(kManufacturer, cellular_->manufacturer());
289 EXPECT_EQ(kModelID, cellular_->model_id());
290 EXPECT_EQ(kHWRev, cellular_->hardware_revision());
291 }
292
TEST_F(CellularCapabilityTest,EnableModemSucceed)293 TEST_F(CellularCapabilityTest, EnableModemSucceed) {
294 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
295 .WillOnce(Invoke(this, &CellularCapabilityTest::InvokeEnable));
296 EXPECT_CALL(*this, TestCallback(IsSuccess()));
297 ResultCallback callback =
298 Bind(&CellularCapabilityTest::TestCallback, Unretained(this));
299 SetProxy();
300 capability_->EnableModem(callback);
301 }
302
TEST_F(CellularCapabilityTest,EnableModemFail)303 TEST_F(CellularCapabilityTest, EnableModemFail) {
304 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
305 .WillOnce(Invoke(this, &CellularCapabilityTest::InvokeEnableFail));
306 EXPECT_CALL(*this, TestCallback(IsFailure()));
307 ResultCallback callback =
308 Bind(&CellularCapabilityTest::TestCallback, Unretained(this));
309 SetProxy();
310 capability_->EnableModem(callback);
311 }
312
TEST_F(CellularCapabilityTest,FinishEnable)313 TEST_F(CellularCapabilityTest, FinishEnable) {
314 EXPECT_CALL(*gsm_network_proxy_,
315 GetRegistrationInfo(nullptr, _,
316 CellularCapability::kTimeoutDefault));
317 EXPECT_CALL(
318 *gsm_network_proxy_,
319 GetSignalQuality(nullptr, _, CellularCapability::kTimeoutDefault));
320 EXPECT_CALL(*this, TestCallback(IsSuccess()));
321 SetGSMNetworkProxy();
322 capability_->FinishEnable(
323 Bind(&CellularCapabilityTest::TestCallback, Unretained(this)));
324 }
325
TEST_F(CellularCapabilityTest,UnsupportedOperation)326 TEST_F(CellularCapabilityTest, UnsupportedOperation) {
327 Error error;
328 EXPECT_CALL(*this, TestCallback(IsSuccess())).Times(0);
329 capability_->CellularCapability::Reset(
330 &error,
331 Bind(&CellularCapabilityTest::TestCallback, Unretained(this)));
332 EXPECT_TRUE(error.IsFailure());
333 EXPECT_EQ(Error::kNotSupported, error.type());
334 }
335
TEST_F(CellularCapabilityTest,AllowRoaming)336 TEST_F(CellularCapabilityTest, AllowRoaming) {
337 EXPECT_FALSE(cellular_->GetAllowRoaming(nullptr));
338 cellular_->SetAllowRoaming(false, nullptr);
339 EXPECT_FALSE(cellular_->GetAllowRoaming(nullptr));
340
341 {
342 InSequence seq;
343 EXPECT_CALL(*device_adaptor_,
344 EmitBoolChanged(kCellularAllowRoamingProperty, true));
345 EXPECT_CALL(*device_adaptor_,
346 EmitBoolChanged(kCellularAllowRoamingProperty, false));
347 }
348
349 cellular_->state_ = Cellular::kStateConnected;
350 static_cast<CellularCapabilityGSM*>(capability_)->registration_state_ =
351 MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
352 cellular_->SetAllowRoaming(true, nullptr);
353 EXPECT_TRUE(cellular_->GetAllowRoaming(nullptr));
354 EXPECT_EQ(Cellular::kStateConnected, cellular_->state_);
355
356 EXPECT_CALL(*proxy_, Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
357 .WillOnce(Invoke(this, &CellularCapabilityTest::InvokeDisconnect));
358 SetProxy();
359 cellular_->state_ = Cellular::kStateConnected;
360 cellular_->SetAllowRoaming(false, nullptr);
361 EXPECT_FALSE(cellular_->GetAllowRoaming(nullptr));
362 EXPECT_EQ(Cellular::kStateRegistered, cellular_->state_);
363 }
364
TEST_F(CellularCapabilityTest,SetCarrier)365 TEST_F(CellularCapabilityTest, SetCarrier) {
366 static const char kCarrier[] = "Generic UMTS";
367 EXPECT_CALL(
368 *gobi_proxy_,
369 SetCarrier(kCarrier, _, _,
370 CellularCapabilityClassic::kTimeoutSetCarrierMilliseconds))
371 .WillOnce(Invoke(this, &CellularCapabilityTest::InvokeSetCarrier));
372 EXPECT_CALL(*this, TestCallback(IsSuccess()));
373 Error error;
374 capability_->SetCarrier(kCarrier, &error,
375 Bind(&CellularCapabilityTest::TestCallback,
376 Unretained(this)));
377 EXPECT_TRUE(error.IsSuccess());
378 }
379
380 MATCHER_P(HasApn, apn, "") {
381 return arg.ContainsString(kApnProperty) && apn == arg.GetString(kApnProperty);
382 }
383
384 MATCHER(HasNoApn, "") {
385 return !arg.ContainsString(kApnProperty);
386 }
387
TEST_F(CellularCapabilityTest,TryApns)388 TEST_F(CellularCapabilityTest, TryApns) {
389 static const string kLastGoodApn("remembered.apn");
390 static const string kLastGoodUsername("remembered.user");
391 static const string kSuppliedApn("my.apn");
392 static const string kTmobileApn1("epc.tmobile.com");
393 static const string kTmobileApn2("wap.voicestream.com");
394 static const string kTmobileApn3("internet2.voicestream.com");
395 static const string kTmobileApn4("internet3.voicestream.com");
396 const Stringmaps kDatabaseApnList {{{ kApnProperty, kTmobileApn1 }},
397 {{ kApnProperty, kTmobileApn2 }},
398 {{ kApnProperty, kTmobileApn3 }},
399 {{ kApnProperty, kTmobileApn4 }}};
400
401
402 CreateService();
403 // Supply the database APNs to |cellular_| object.
404 cellular_->set_apn_list(kDatabaseApnList);
405 ProfileRefPtr profile(new NiceMock<MockProfile>(
406 modem_info_.control_interface(), modem_info_.metrics(),
407 modem_info_.manager()));
408 cellular_->service()->set_profile(profile);
409
410 Error error;
411 Stringmap apn_info;
412 KeyValueStore props;
413 CellularCapabilityGSM* gsm_capability = GetGsmCapability();
414
415 apn_info[kApnProperty] = kLastGoodApn;
416 apn_info[kApnUsernameProperty] = kLastGoodUsername;
417 cellular_->service()->SetLastGoodApn(apn_info);
418 props.Clear();
419 EXPECT_TRUE(props.IsEmpty());
420 gsm_capability->SetupConnectProperties(&props);
421 // We expect the list to contain the last good APN, plus
422 // the 4 APNs from the mobile provider info database.
423 EXPECT_EQ(5, gsm_capability->apn_try_list_.size());
424 EXPECT_TRUE(props.ContainsString(kApnProperty));
425 EXPECT_EQ(kLastGoodApn, props.GetString(kApnProperty));
426 EXPECT_TRUE(props.ContainsString(kApnUsernameProperty));
427 EXPECT_EQ(kLastGoodUsername,
428 props.GetString(kApnUsernameProperty));
429
430 apn_info.clear();
431 props.Clear();
432 apn_info[kApnProperty] = kSuppliedApn;
433 // Setting the APN has the side effect of clearing the LastGoodApn,
434 // so the try list will have 5 elements, with the first one being
435 // the supplied APN.
436 cellular_->service()->SetApn(apn_info, &error);
437 EXPECT_TRUE(props.IsEmpty());
438 gsm_capability->SetupConnectProperties(&props);
439 EXPECT_EQ(5, gsm_capability->apn_try_list_.size());
440 EXPECT_TRUE(props.ContainsString(kApnProperty));
441 EXPECT_EQ(kSuppliedApn, props.GetString(kApnProperty));
442
443 apn_info.clear();
444 props.Clear();
445 apn_info[kApnProperty] = kLastGoodApn;
446 apn_info[kApnUsernameProperty] = kLastGoodUsername;
447 // Now when LastGoodAPN is set, it will be the one selected.
448 cellular_->service()->SetLastGoodApn(apn_info);
449 EXPECT_TRUE(props.IsEmpty());
450 gsm_capability->SetupConnectProperties(&props);
451 // We expect the list to contain the last good APN, plus
452 // the user-supplied APN, plus the 4 APNs from the mobile
453 // provider info database.
454 EXPECT_EQ(6, gsm_capability->apn_try_list_.size());
455 EXPECT_TRUE(props.ContainsString(kApnProperty));
456 EXPECT_EQ(kLastGoodApn, props.GetString(kApnProperty));
457
458 // Now try all the given APNs.
459 using testing::InSequence;
460 {
461 InSequence dummy;
462 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kLastGoodApn), _, _, _));
463 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kSuppliedApn), _, _, _));
464 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kTmobileApn1), _, _, _));
465 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kTmobileApn2), _, _, _));
466 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kTmobileApn3), _, _, _));
467 EXPECT_CALL(*simple_proxy_, Connect(HasApn(kTmobileApn4), _, _, _));
468 EXPECT_CALL(*simple_proxy_, Connect(HasNoApn(), _, _, _));
469 }
470 SetSimpleProxy();
471 gsm_capability->Connect(props, &error, ResultCallback());
472 Error cerror(Error::kInvalidApn);
473 gsm_capability->OnConnectReply(ResultCallback(), cerror);
474 EXPECT_EQ(5, gsm_capability->apn_try_list_.size());
475 gsm_capability->OnConnectReply(ResultCallback(), cerror);
476 EXPECT_EQ(4, gsm_capability->apn_try_list_.size());
477 gsm_capability->OnConnectReply(ResultCallback(), cerror);
478 EXPECT_EQ(3, gsm_capability->apn_try_list_.size());
479 gsm_capability->OnConnectReply(ResultCallback(), cerror);
480 EXPECT_EQ(2, gsm_capability->apn_try_list_.size());
481 gsm_capability->OnConnectReply(ResultCallback(), cerror);
482 EXPECT_EQ(1, gsm_capability->apn_try_list_.size());
483 gsm_capability->OnConnectReply(ResultCallback(), cerror);
484 EXPECT_EQ(0, gsm_capability->apn_try_list_.size());
485 }
486
TEST_F(CellularCapabilityTest,StopModemDisconnectSuccess)487 TEST_F(CellularCapabilityTest, StopModemDisconnectSuccess) {
488 EXPECT_CALL(*proxy_, Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
489 .WillOnce(Invoke(this,
490 &CellularCapabilityTest::InvokeDisconnect));
491 EXPECT_CALL(*proxy_, Enable(_, _, _, CellularCapability::kTimeoutEnable))
492 .WillOnce(Invoke(this,
493 &CellularCapabilityTest::InvokeEnable));
494 EXPECT_CALL(*this, TestCallback(IsSuccess()));
495 SetProxy();
496
497 Error error;
498 capability_->StopModem(
499 &error, Bind(&CellularCapabilityTest::TestCallback, Unretained(this)));
500 dispatcher_.DispatchPendingEvents();
501 }
502
TEST_F(CellularCapabilityTest,StopModemDisconnectFail)503 TEST_F(CellularCapabilityTest, StopModemDisconnectFail) {
504 EXPECT_CALL(*proxy_, Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
505 .WillOnce(Invoke(this,
506 &CellularCapabilityTest::InvokeDisconnectFail));
507 EXPECT_CALL(*proxy_, Enable(_, _, _, CellularCapability::kTimeoutEnable))
508 .WillOnce(Invoke(this,
509 &CellularCapabilityTest::InvokeEnable));
510 EXPECT_CALL(*this, TestCallback(IsSuccess()));
511 SetProxy();
512
513 Error error;
514 capability_->StopModem(
515 &error, Bind(&CellularCapabilityTest::TestCallback, Unretained(this)));
516 dispatcher_.DispatchPendingEvents();
517 }
518
TEST_F(CellularCapabilityTest,DisconnectNoProxy)519 TEST_F(CellularCapabilityTest, DisconnectNoProxy) {
520 Error error;
521 ResultCallback disconnect_callback;
522 EXPECT_CALL(*proxy_, Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
523 .Times(0);
524 ReleaseCapabilityProxies();
525 capability_->Disconnect(&error, disconnect_callback);
526 }
527
528 } // namespace shill
529