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