blob: 7c9b3b865b73014f77b1e4e8fffc5d04247a9798 [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>
Jason Glasgowaf583282012-04-18 15:18:22 -040014#include <mm/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
Jason Glasgowaf583282012-04-18 15:18:22 -0400345TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
346 // Set up mock modem properties
347 DBusPropertiesMap modem_properties;
348 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
349 writer().append_uint32(kAccessTechnologies);
350 modem_properties[MM_MODEM_PROPERTY_SIM].
351 writer().append_path(kSimPath);
352
353 // Set up mock modem 3gpp properties
354 DBusPropertiesMap modem3gpp_properties;
355 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
356 writer().append_uint32(0);
357 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
358 writer().append_string(kImei);
359
360 // Set up mock modem sim properties
361 DBusPropertiesMap sim_properties;
362
363 // After setup we lose pointers to the proxies, so it is hard to set
364 // expectations.
365 EXPECT_CALL(*properties_proxy_,
366 GetAll(MM_DBUS_INTERFACE_SIM))
367 .WillOnce(Return(sim_properties));
368
369 SetUp();
370
371 EXPECT_EQ("", capability_->imei_);
372 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
373 capability_->access_technologies_);
374 EXPECT_FALSE(capability_->sim_proxy_.get());
Jason Glasgowbad114b2012-05-21 15:24:16 -0400375 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
376 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm));
Jason Glasgowaf583282012-04-18 15:18:22 -0400377 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
378 modem_properties, vector<string>());
379 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
380 EXPECT_EQ(kSimPath, capability_->sim_path_);
381 EXPECT_TRUE(capability_->sim_proxy_.get());
382
383 // Changing properties on wrong interface will not have an effect
384 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
385 modem3gpp_properties,
386 vector<string>());
387 EXPECT_EQ("", capability_->imei_);
388
389 // Changing properties on the right interface gets reflected in the
390 // capabilities object
391 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
392 modem3gpp_properties,
393 vector<string>());
394 EXPECT_EQ(kImei, capability_->imei_);
Jason Glasgowbad114b2012-05-21 15:24:16 -0400395
396 // Expect to see changes when the family changes
397 modem_properties.clear();
398 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
399 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
400 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
401 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyCdma)).
402 Times(1);
403 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
404 modem_properties,
405 vector<string>());
406 // Back to LTE
407 modem_properties.clear();
408 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
409 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE);
410 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
411 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm)).
412 Times(1);
413 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
414 modem_properties,
415 vector<string>());
416
417 // LTE & CDMA - the device adaptor should not be called!
418 modem_properties.clear();
419 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
420 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE |
421 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
422 EXPECT_CALL(*device_adaptor_, EmitStringChanged(_, _)).Times(0);
423 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
424 modem_properties,
425 vector<string>());
Jason Glasgowaf583282012-04-18 15:18:22 -0400426}
427
428TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
429 // Set up mock modem properties
430 DBusPropertiesMap modem_properties;
431 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
432
433 // Set up mock modem sim properties
434 const char kImsi[] = "310100000001";
435 DBusPropertiesMap sim_properties;
436 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
437
438 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
439 .WillOnce(Return(sim_properties));
440
441 // After setup we lose pointers to the proxies, so it is hard to set
442 // expectations.
443 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400444 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400445
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400446 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
447 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
448 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400449 EXPECT_FALSE(capability_->sim_proxy_.get());
450 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
451 modem_properties, vector<string>());
452 EXPECT_EQ(kSimPath, capability_->sim_path_);
453 EXPECT_TRUE(capability_->sim_proxy_.get());
454 EXPECT_EQ(kImsi, capability_->imsi_);
455
456 // Updating the SIM
457 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400458 const char kCountry[] = "us";
459 const char kCode[] = "310160";
460 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400461 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400462 const char kOperatorIdentifier[] = "310240";
463 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400464 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
465 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
466 append_string(kSimIdentifier);
467 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
468 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400469 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
470 new_properties,
471 vector<string>());
472 EXPECT_EQ(kNewImsi, capability_->imsi_);
473 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
474 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400475 EXPECT_EQ("", capability_->spn_);
476 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
477 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
478 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
479 EXPECT_EQ(4, capability_->apn_list_.size());
480
481 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
482 append_string(kOperatorName);
483 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
484 new_properties,
485 vector<string>());
486 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400487 EXPECT_EQ(kOperatorName, capability_->spn_);
488}
489
Gary Morainceba6aa2012-05-03 10:28:26 -0700490MATCHER_P(SizeIs, value, "") {
491 return static_cast<size_t>(value) == arg.size();
492}
493
494// Validates that OnScanReply does not crash with a null callback.
495TEST_F(CellularCapabilityUniversalTest, ScanWithNullCallback) {
496 Error error;
497 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
498 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeScan));
499 EXPECT_CALL(*device_adaptor_,
500 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
501 SizeIs(0)));
502 Set3gppProxy();
503 capability_->Scan(&error, ResultCallback());
504 EXPECT_TRUE(error.IsSuccess());
505}
506
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400507// Validates that the scanning property is updated
508TEST_F(CellularCapabilityUniversalTest, Scan) {
509 Error error;
510
511 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
512 .WillRepeatedly(SaveArg<1>(&scan_callback_));
513 EXPECT_CALL(*device_adaptor_,
514 EmitBoolChanged(flimflam::kScanningProperty, true));
515 Set3gppProxy();
516 capability_->Scan(&error, ResultCallback());
517 EXPECT_TRUE(capability_->scanning_);
518
519 // Simulate the completion of the scan with 2 networks in the results.
520 EXPECT_CALL(*device_adaptor_,
521 EmitBoolChanged(flimflam::kScanningProperty, false));
522 EXPECT_CALL(*device_adaptor_,
523 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
524 SizeIs(2)));
525 vector<DBusPropertiesMap> results;
526 const char kScanID0[] = "testID0";
527 const char kScanID1[] = "testID1";
528 results.push_back(DBusPropertiesMap());
529 results[0][CellularCapabilityUniversal::kOperatorLongProperty].
530 writer().append_string(kScanID0);
531 results.push_back(DBusPropertiesMap());
532 results[1][CellularCapabilityUniversal::kOperatorLongProperty].
533 writer().append_string(kScanID1);
534 scan_callback_.Run(results, error);
535 EXPECT_FALSE(capability_->scanning_);
536
537 // Simulate the completion of the scan with no networks in the results.
538 EXPECT_CALL(*device_adaptor_,
539 EmitBoolChanged(flimflam::kScanningProperty, true));
540 capability_->Scan(&error, ResultCallback());
541 EXPECT_TRUE(capability_->scanning_);
542 EXPECT_CALL(*device_adaptor_,
543 EmitBoolChanged(flimflam::kScanningProperty, false));
544 EXPECT_CALL(*device_adaptor_,
545 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
546 SizeIs(0)));
547 scan_callback_.Run(vector<DBusPropertiesMap>(), Error());
548 EXPECT_FALSE(capability_->scanning_);
549}
550
551// Validates expected property updates when scan fails
552TEST_F(CellularCapabilityUniversalTest, ScanFailure) {
553 Error error;
554
555 // Test immediate error
556 {
557 InSequence seq;
558 EXPECT_CALL(*modem_3gpp_proxy_,
559 Scan(_, _, CellularCapability::kTimeoutScan))
560 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::ScanError));
561 EXPECT_CALL(*modem_3gpp_proxy_,
562 Scan(_, _, CellularCapability::kTimeoutScan))
563 .WillOnce(SaveArg<1>(&scan_callback_));
564 }
565 Set3gppProxy();
566 capability_->Scan(&error, ResultCallback());
567 EXPECT_FALSE(capability_->scanning_);
568 EXPECT_TRUE(error.IsFailure());
569
570 // Initiate a scan
571 error.Populate(Error::kSuccess);
572 EXPECT_CALL(*device_adaptor_,
573 EmitBoolChanged(flimflam::kScanningProperty, true));
574 capability_->Scan(&error, ResultCallback());
575 EXPECT_TRUE(capability_->scanning_);
576 EXPECT_TRUE(error.IsSuccess());
577
578 // Validate that error is returned if Scan is called while already scanning.
579 capability_->Scan(&error, ResultCallback());
580 EXPECT_TRUE(capability_->scanning_);
581 EXPECT_TRUE(error.IsFailure());
582
583 // Validate that signals are emitted even if an error is reported.
584 capability_->found_networks_.clear();
585 capability_->found_networks_.push_back(Stringmap());
586 EXPECT_CALL(*device_adaptor_,
587 EmitBoolChanged(flimflam::kScanningProperty, false));
588 EXPECT_CALL(*device_adaptor_,
589 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
590 SizeIs(0)));
591 vector<DBusPropertiesMap> results;
592 scan_callback_.Run(results, Error(Error::kOperationFailed));
593 EXPECT_FALSE(capability_->scanning_);
594}
595
Jason Glasgow14521872012-05-07 19:12:15 -0400596// Validates expected behavior of Connect function
597TEST_F(CellularCapabilityUniversalTest, Connect) {
598 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
599 SetSimpleProxy();
600 Error error;
601 DBusPropertiesMap properties;
602 capability_->apn_try_list_.clear();
603 ResultCallback callback =
604 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
605 DBus::Path bearer("/foo");
606
607 // Test connect failures
608 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
609 .WillOnce(SaveArg<2>(&connect_callback_));
610 capability_->Connect(properties, &error, callback);
611 EXPECT_TRUE(error.IsSuccess());
612 EXPECT_CALL(*this, TestCallback(IsFailure()));
613 EXPECT_CALL(*service_, ClearLastGoodApn());
614 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
615
616 // Test connect success
617 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
618 .WillOnce(SaveArg<2>(&connect_callback_));
619 capability_->Connect(properties, &error, callback);
620 EXPECT_TRUE(error.IsSuccess());
621 EXPECT_CALL(*this, TestCallback(IsSuccess()));
622 connect_callback_.Run(bearer, Error(Error::kSuccess));
Jason Glasgow7234ec32012-05-23 16:01:21 -0400623
624 // Test connect failures without a service. Make sure that shill
625 // does not crash if the connect failed and there is no
626 // CellularService object. This can happen if the modem is enabled
627 // and then quickly disabled.
628 cellular_->service_ = NULL;
629 EXPECT_FALSE(capability_->cellular()->service());
630 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
631 .WillOnce(SaveArg<2>(&connect_callback_));
632 capability_->Connect(properties, &error, callback);
633 EXPECT_TRUE(error.IsSuccess());
634 EXPECT_CALL(*this, TestCallback(IsFailure()));
635 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
Jason Glasgow14521872012-05-07 19:12:15 -0400636}
637
638// Validates Connect iterates over APNs
639TEST_F(CellularCapabilityUniversalTest, ConnectApns) {
640 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
641 SetSimpleProxy();
642 Error error;
643 DBusPropertiesMap properties;
644 capability_->apn_try_list_.clear();
645 ResultCallback callback =
646 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
647 DBus::Path bearer("/bearer0");
648
649 const char apn_name_foo[] = "foo";
650 const char apn_name_bar[] = "bar";
651 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_foo), _, _, _))
652 .WillOnce(SaveArg<2>(&connect_callback_));
653 Stringmap apn1;
654 apn1[flimflam::kApnProperty] = apn_name_foo;
655 capability_->apn_try_list_.push_back(apn1);
656 Stringmap apn2;
657 apn2[flimflam::kApnProperty] = apn_name_bar;
658 capability_->apn_try_list_.push_back(apn2);
659 capability_->FillConnectPropertyMap(&properties);
660 capability_->Connect(properties, &error, callback);
661 EXPECT_TRUE(error.IsSuccess());
662
663 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_bar), _, _, _))
664 .WillOnce(SaveArg<2>(&connect_callback_));
665 EXPECT_CALL(*service_, ClearLastGoodApn());
666 connect_callback_.Run(bearer, Error(Error::kInvalidApn));
667
668 EXPECT_CALL(*service_, SetLastGoodApn(apn2));
669 EXPECT_CALL(*this, TestCallback(IsSuccess()));
670 connect_callback_.Run(bearer, Error(Error::kSuccess));
671}
672
Jason Glasgow9f09aef2012-05-08 16:26:55 -0400673// Validates GetTypeString and AccessTechnologyToTechnologyFamily
674TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
675 const int gsm_technologies[] = {
676 MM_MODEM_ACCESS_TECHNOLOGY_LTE,
677 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
678 MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
679 MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
680 MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
681 MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
682 MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
683 MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
684 MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
685 MM_MODEM_ACCESS_TECHNOLOGY_GSM,
686 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
687 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
688 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
689 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
690 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
691 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
692 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
693 };
694 for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
695 capability_->access_technologies_ = gsm_technologies[i];
696 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
697 }
698 const int cdma_technologies[] = {
699 MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
700 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
701 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
702 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
703 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
704 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
705 };
706 for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
707 capability_->access_technologies_ = cdma_technologies[i];
708 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
709 }
710 capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
711 ASSERT_EQ(capability_->GetTypeString(), "");
712}
713
Jason Glasgowef965562012-04-10 16:12:35 -0400714} // namespace shill