blob: c3b1330c58d34f0557721f1d5ffd4fe64ab49e63 [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 "",
77 NULL)),
Jason Glasgow14521872012-05-07 19:12:15 -040078 service_(new MockCellularService(&control_,
79 &dispatcher_,
80 &metrics_,
81 &manager_,
82 cellular_)),
Jason Glasgowef965562012-04-10 16:12:35 -040083 modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
84 modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
85 modem_proxy_(new mm1::MockModemProxy()),
86 modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
87 sim_proxy_(new mm1::MockSimProxy()),
Jason Glasgowaf583282012-04-18 15:18:22 -040088 properties_proxy_(new MockDBusPropertiesProxy()),
Jason Glasgowef965562012-04-10 16:12:35 -040089 proxy_factory_(this),
90 capability_(NULL),
91 device_adaptor_(NULL) {}
92
93 virtual ~CellularCapabilityUniversalTest() {
94 cellular_->service_ = NULL;
95 capability_ = NULL;
96 device_adaptor_ = NULL;
97 }
98
99 virtual void SetUp() {
100 capability_ = dynamic_cast<CellularCapabilityUniversal *>(
101 cellular_->capability_.get());
102 capability_->proxy_factory_ = &proxy_factory_;
103 device_adaptor_ =
104 dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
Jason Glasgow14521872012-05-07 19:12:15 -0400105 cellular_->service_ = service_;
Jason Glasgowef965562012-04-10 16:12:35 -0400106 }
107
108 virtual void TearDown() {
109 capability_->proxy_factory_ = NULL;
110 }
111
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400112 void InitProviderDB() {
113 const char kTestMobileProviderDBPath[] = "provider_db_unittest.bfd";
114
115 provider_db_ = mobile_provider_open_db(kTestMobileProviderDBPath);
116 ASSERT_TRUE(provider_db_);
117 cellular_->provider_db_ = provider_db_;
118 }
119
Jason Glasgowef965562012-04-10 16:12:35 -0400120 void InvokeEnable(bool enable, Error *error,
121 const ResultCallback &callback, int timeout) {
122 callback.Run(Error());
123 }
124 void InvokeEnableFail(bool enable, Error *error,
125 const ResultCallback &callback, int timeout) {
126 callback.Run(Error(Error::kOperationFailed));
127 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400128 void InvokeRegister(const string &operator_id, Error *error,
129 const ResultCallback &callback, int timeout) {
130 callback.Run(Error());
131 }
132
Gary Morainceba6aa2012-05-03 10:28:26 -0700133 void InvokeScan(Error *error, const DBusPropertyMapsCallback &callback,
134 int timeout) {
135 callback.Run(CellularCapabilityUniversal::ScanResults(), Error());
136 }
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400137 void ScanError(Error *error, const DBusPropertyMapsCallback &callback,
138 int timeout) {
139 error->Populate(Error::kOperationFailed);
140 }
Gary Morainceba6aa2012-05-03 10:28:26 -0700141
142 void Set3gppProxy() {
143 capability_->modem_3gpp_proxy_.reset(modem_3gpp_proxy_.release());
144 }
145
Jason Glasgow14521872012-05-07 19:12:15 -0400146 void SetSimpleProxy() {
147 capability_->modem_simple_proxy_.reset(modem_simple_proxy_.release());
148 }
149
Jason Glasgowef965562012-04-10 16:12:35 -0400150 MOCK_METHOD1(TestCallback, void(const Error &error));
151
152 protected:
153 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400154 static const char kSimPath[];
155 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400156
157 class TestProxyFactory : public ProxyFactory {
158 public:
159 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
160 test_(test) {}
161
162 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
163 const std::string &/* path */,
164 const std::string &/* service */) {
165 return test_->modem_3gpp_proxy_.release();
166 }
167
168 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
169 const std::string &/* path */,
170 const std::string &/* service */) {
171 return test_->modem_cdma_proxy_.release();
172 }
173
174 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
175 const std::string &/* path */,
176 const std::string &/* service */) {
177 return test_->modem_proxy_.release();
178 }
179
180 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
181 const std::string &/* path */,
182 const std::string &/* service */) {
183 return test_->modem_simple_proxy_.release();
184 }
185
186 virtual mm1::SimProxyInterface *CreateSimProxy(
187 const std::string &/* path */,
188 const std::string &/* service */) {
189 return test_->sim_proxy_.release();
190 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400191 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
192 const std::string &/* path */,
193 const std::string &/* service */) {
194 return test_->properties_proxy_.release();
195 }
Jason Glasgowef965562012-04-10 16:12:35 -0400196
197 private:
198 CellularCapabilityUniversalTest *test_;
199 };
200
201 NiceMockControl control_;
202 EventDispatcher dispatcher_;
203 MockMetrics metrics_;
204 MockGLib glib_;
205 MockManager manager_;
206 CellularRefPtr cellular_;
Jason Glasgow14521872012-05-07 19:12:15 -0400207 MockCellularService *service_; // owned by cellular_
Jason Glasgowef965562012-04-10 16:12:35 -0400208 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
209 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
210 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
211 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
212 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400213 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400214 TestProxyFactory proxy_factory_;
215 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
216 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400217 mobile_provider_db *provider_db_;
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400218 DBusPropertyMapsCallback scan_callback_; // saved for testing scan operations
Jason Glasgow14521872012-05-07 19:12:15 -0400219 DBusPathCallback connect_callback_; // saved for testing connect operations
Jason Glasgowef965562012-04-10 16:12:35 -0400220};
221
222const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400223const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
224const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
225 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
226 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400227
228TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400229 // Set up mock modem properties
230 DBusPropertiesMap modem_properties;
231 string operator_name = "TestOperator";
232 string operator_code = "001400";
233
234 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
235 writer().append_uint32(kAccessTechnologies);
236
237 ::DBus::Variant v;
238 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400239 ::DBus::Struct< uint32_t, bool > quality;
240 quality._1 = 90;
241 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400242 writer << quality;
243 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
244
245 // Set up mock modem 3gpp properties
246 DBusPropertiesMap modem3gpp_properties;
247 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
248 writer().append_uint32(0);
249 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
250 writer().append_string(kImei);
251
252 EXPECT_CALL(*modem_proxy_,
253 Enable(true, _, _, CellularCapability::kTimeoutEnable))
254 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
255 EXPECT_CALL(*properties_proxy_,
256 GetAll(MM_DBUS_INTERFACE_MODEM))
257 .WillOnce(Return(modem_properties));
258 EXPECT_CALL(*properties_proxy_,
259 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
260 .WillOnce(Return(modem3gpp_properties));
Jason Glasgowef965562012-04-10 16:12:35 -0400261
262 // After setup we lose pointers to the proxies, so it is hard to set
263 // expectations.
264 SetUp();
265
266 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400267 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400268 ResultCallback callback =
269 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
270 capability_->StartModem(&error, callback);
271 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400272 EXPECT_EQ(kImei, capability_->imei_);
273 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400274}
275
276TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
277 EXPECT_CALL(*modem_proxy_,
278 Enable(true, _, _, CellularCapability::kTimeoutEnable))
279 .WillOnce(
280 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
281 EXPECT_CALL(*this, TestCallback(IsFailure()));
282 ResultCallback callback =
283 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
284 SetUp();
285
286 Error error;
287 capability_->StartModem(&error, callback);
288 EXPECT_TRUE(error.IsSuccess());
289}
290
Jason Glasgow02401cc2012-05-16 10:35:37 -0400291TEST_F(CellularCapabilityUniversalTest, StopModem) {
292 // Save pointers to proxies before they are lost by the call to InitProxies
293 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
294 SetUp();
295 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
296 capability_->InitProxies();
297
298 Error error;
299 ResultCallback callback =
300 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
301 capability_->StopModem(&error, callback);
302 EXPECT_TRUE(error.IsSuccess());
303
304 ResultCallback disable_callback;
305 EXPECT_CALL(*modem_proxy,
306 Enable(false, _, _, CellularCapability::kTimeoutEnable))
307 .WillOnce(SaveArg<2>(&disable_callback));
308 dispatcher_.DispatchPendingEvents();
309
310 EXPECT_CALL(*this, TestCallback(IsSuccess()));
311 disable_callback.Run(Error(Error::kSuccess));
312}
313
314TEST_F(CellularCapabilityUniversalTest, StopModemConnected) {
315 // Save pointers to proxies before they are lost by the call to InitProxies
316 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
317 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
318 SetUp();
319 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
320 capability_->InitProxies();
321
322 ResultCallback disconnect_callback;
323 Error error;
324 ResultCallback callback =
325 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
326 EXPECT_CALL(*modem_simple_proxy,
327 Disconnect(::DBus::Path("/"), _, _,
328 CellularCapability::kTimeoutDefault))
329 .WillOnce(SaveArg<2>(&disconnect_callback));
330 capability_->cellular()->state_ = Cellular::kStateConnected;
331 capability_->StopModem(&error, callback);
332 EXPECT_TRUE(error.IsSuccess());
333
334 ResultCallback disable_callback;
335 EXPECT_CALL(*modem_proxy,
336 Enable(false, _, _, CellularCapability::kTimeoutEnable))
337 .WillOnce(SaveArg<2>(&disable_callback));
338 disconnect_callback.Run(Error(Error::kSuccess));
339
340 EXPECT_CALL(*this, TestCallback(IsSuccess()));
341 disable_callback.Run(Error(Error::kSuccess));
342}
343
Jason Glasgowaf583282012-04-18 15:18:22 -0400344TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
345 // Set up mock modem properties
346 DBusPropertiesMap modem_properties;
347 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
348 writer().append_uint32(kAccessTechnologies);
349 modem_properties[MM_MODEM_PROPERTY_SIM].
350 writer().append_path(kSimPath);
351
352 // Set up mock modem 3gpp properties
353 DBusPropertiesMap modem3gpp_properties;
354 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
355 writer().append_uint32(0);
356 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
357 writer().append_string(kImei);
358
359 // Set up mock modem sim properties
360 DBusPropertiesMap sim_properties;
361
362 // After setup we lose pointers to the proxies, so it is hard to set
363 // expectations.
364 EXPECT_CALL(*properties_proxy_,
365 GetAll(MM_DBUS_INTERFACE_SIM))
366 .WillOnce(Return(sim_properties));
367
368 SetUp();
369
370 EXPECT_EQ("", capability_->imei_);
371 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
372 capability_->access_technologies_);
373 EXPECT_FALSE(capability_->sim_proxy_.get());
Jason Glasgowbad114b2012-05-21 15:24:16 -0400374 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
375 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm));
Jason Glasgowaf583282012-04-18 15:18:22 -0400376 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
377 modem_properties, vector<string>());
378 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
379 EXPECT_EQ(kSimPath, capability_->sim_path_);
380 EXPECT_TRUE(capability_->sim_proxy_.get());
381
382 // Changing properties on wrong interface will not have an effect
383 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
384 modem3gpp_properties,
385 vector<string>());
386 EXPECT_EQ("", capability_->imei_);
387
388 // Changing properties on the right interface gets reflected in the
389 // capabilities object
390 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
391 modem3gpp_properties,
392 vector<string>());
393 EXPECT_EQ(kImei, capability_->imei_);
Jason Glasgowbad114b2012-05-21 15:24:16 -0400394
395 // Expect to see changes when the family changes
396 modem_properties.clear();
397 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
398 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
399 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
400 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyCdma)).
401 Times(1);
402 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
403 modem_properties,
404 vector<string>());
405 // Back to LTE
406 modem_properties.clear();
407 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
408 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE);
409 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
410 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm)).
411 Times(1);
412 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
413 modem_properties,
414 vector<string>());
415
416 // LTE & CDMA - the device adaptor should not be called!
417 modem_properties.clear();
418 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
419 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE |
420 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
421 EXPECT_CALL(*device_adaptor_, EmitStringChanged(_, _)).Times(0);
422 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
423 modem_properties,
424 vector<string>());
Jason Glasgowaf583282012-04-18 15:18:22 -0400425}
426
427TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
428 // Set up mock modem properties
429 DBusPropertiesMap modem_properties;
430 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
431
432 // Set up mock modem sim properties
433 const char kImsi[] = "310100000001";
434 DBusPropertiesMap sim_properties;
435 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
436
437 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
438 .WillOnce(Return(sim_properties));
439
440 // After setup we lose pointers to the proxies, so it is hard to set
441 // expectations.
442 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400443 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400444
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400445 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
446 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
447 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400448 EXPECT_FALSE(capability_->sim_proxy_.get());
449 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
450 modem_properties, vector<string>());
451 EXPECT_EQ(kSimPath, capability_->sim_path_);
452 EXPECT_TRUE(capability_->sim_proxy_.get());
453 EXPECT_EQ(kImsi, capability_->imsi_);
454
455 // Updating the SIM
456 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400457 const char kCountry[] = "us";
458 const char kCode[] = "310160";
459 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400460 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400461 const char kOperatorIdentifier[] = "310240";
462 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400463 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
464 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
465 append_string(kSimIdentifier);
466 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
467 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400468 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
469 new_properties,
470 vector<string>());
471 EXPECT_EQ(kNewImsi, capability_->imsi_);
472 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
473 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400474 EXPECT_EQ("", capability_->spn_);
475 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
476 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
477 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
478 EXPECT_EQ(4, capability_->apn_list_.size());
479
480 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
481 append_string(kOperatorName);
482 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
483 new_properties,
484 vector<string>());
485 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400486 EXPECT_EQ(kOperatorName, capability_->spn_);
487}
488
Gary Morainceba6aa2012-05-03 10:28:26 -0700489MATCHER_P(SizeIs, value, "") {
490 return static_cast<size_t>(value) == arg.size();
491}
492
493// Validates that OnScanReply does not crash with a null callback.
494TEST_F(CellularCapabilityUniversalTest, ScanWithNullCallback) {
495 Error error;
496 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
497 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeScan));
498 EXPECT_CALL(*device_adaptor_,
499 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
500 SizeIs(0)));
501 Set3gppProxy();
502 capability_->Scan(&error, ResultCallback());
503 EXPECT_TRUE(error.IsSuccess());
504}
505
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400506// Validates that the scanning property is updated
507TEST_F(CellularCapabilityUniversalTest, Scan) {
508 Error error;
509
510 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
511 .WillRepeatedly(SaveArg<1>(&scan_callback_));
512 EXPECT_CALL(*device_adaptor_,
513 EmitBoolChanged(flimflam::kScanningProperty, true));
514 Set3gppProxy();
515 capability_->Scan(&error, ResultCallback());
516 EXPECT_TRUE(capability_->scanning_);
517
518 // Simulate the completion of the scan with 2 networks in the results.
519 EXPECT_CALL(*device_adaptor_,
520 EmitBoolChanged(flimflam::kScanningProperty, false));
521 EXPECT_CALL(*device_adaptor_,
522 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
523 SizeIs(2)));
524 vector<DBusPropertiesMap> results;
525 const char kScanID0[] = "testID0";
526 const char kScanID1[] = "testID1";
527 results.push_back(DBusPropertiesMap());
528 results[0][CellularCapabilityUniversal::kOperatorLongProperty].
529 writer().append_string(kScanID0);
530 results.push_back(DBusPropertiesMap());
531 results[1][CellularCapabilityUniversal::kOperatorLongProperty].
532 writer().append_string(kScanID1);
533 scan_callback_.Run(results, error);
534 EXPECT_FALSE(capability_->scanning_);
535
536 // Simulate the completion of the scan with no networks in the results.
537 EXPECT_CALL(*device_adaptor_,
538 EmitBoolChanged(flimflam::kScanningProperty, true));
539 capability_->Scan(&error, ResultCallback());
540 EXPECT_TRUE(capability_->scanning_);
541 EXPECT_CALL(*device_adaptor_,
542 EmitBoolChanged(flimflam::kScanningProperty, false));
543 EXPECT_CALL(*device_adaptor_,
544 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
545 SizeIs(0)));
546 scan_callback_.Run(vector<DBusPropertiesMap>(), Error());
547 EXPECT_FALSE(capability_->scanning_);
548}
549
550// Validates expected property updates when scan fails
551TEST_F(CellularCapabilityUniversalTest, ScanFailure) {
552 Error error;
553
554 // Test immediate error
555 {
556 InSequence seq;
557 EXPECT_CALL(*modem_3gpp_proxy_,
558 Scan(_, _, CellularCapability::kTimeoutScan))
559 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::ScanError));
560 EXPECT_CALL(*modem_3gpp_proxy_,
561 Scan(_, _, CellularCapability::kTimeoutScan))
562 .WillOnce(SaveArg<1>(&scan_callback_));
563 }
564 Set3gppProxy();
565 capability_->Scan(&error, ResultCallback());
566 EXPECT_FALSE(capability_->scanning_);
567 EXPECT_TRUE(error.IsFailure());
568
569 // Initiate a scan
570 error.Populate(Error::kSuccess);
571 EXPECT_CALL(*device_adaptor_,
572 EmitBoolChanged(flimflam::kScanningProperty, true));
573 capability_->Scan(&error, ResultCallback());
574 EXPECT_TRUE(capability_->scanning_);
575 EXPECT_TRUE(error.IsSuccess());
576
577 // Validate that error is returned if Scan is called while already scanning.
578 capability_->Scan(&error, ResultCallback());
579 EXPECT_TRUE(capability_->scanning_);
580 EXPECT_TRUE(error.IsFailure());
581
582 // Validate that signals are emitted even if an error is reported.
583 capability_->found_networks_.clear();
584 capability_->found_networks_.push_back(Stringmap());
585 EXPECT_CALL(*device_adaptor_,
586 EmitBoolChanged(flimflam::kScanningProperty, false));
587 EXPECT_CALL(*device_adaptor_,
588 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
589 SizeIs(0)));
590 vector<DBusPropertiesMap> results;
591 scan_callback_.Run(results, Error(Error::kOperationFailed));
592 EXPECT_FALSE(capability_->scanning_);
593}
594
Jason Glasgow14521872012-05-07 19:12:15 -0400595// Validates expected behavior of Connect function
596TEST_F(CellularCapabilityUniversalTest, Connect) {
597 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
598 SetSimpleProxy();
599 Error error;
600 DBusPropertiesMap properties;
601 capability_->apn_try_list_.clear();
602 ResultCallback callback =
603 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
604 DBus::Path bearer("/foo");
605
606 // Test connect failures
607 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
608 .WillOnce(SaveArg<2>(&connect_callback_));
609 capability_->Connect(properties, &error, callback);
610 EXPECT_TRUE(error.IsSuccess());
611 EXPECT_CALL(*this, TestCallback(IsFailure()));
612 EXPECT_CALL(*service_, ClearLastGoodApn());
613 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
614
615 // Test connect success
616 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
617 .WillOnce(SaveArg<2>(&connect_callback_));
618 capability_->Connect(properties, &error, callback);
619 EXPECT_TRUE(error.IsSuccess());
620 EXPECT_CALL(*this, TestCallback(IsSuccess()));
621 connect_callback_.Run(bearer, Error(Error::kSuccess));
Jason Glasgow7234ec32012-05-23 16:01:21 -0400622
623 // Test connect failures without a service. Make sure that shill
624 // does not crash if the connect failed and there is no
625 // CellularService object. This can happen if the modem is enabled
626 // and then quickly disabled.
627 cellular_->service_ = NULL;
628 EXPECT_FALSE(capability_->cellular()->service());
629 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
630 .WillOnce(SaveArg<2>(&connect_callback_));
631 capability_->Connect(properties, &error, callback);
632 EXPECT_TRUE(error.IsSuccess());
633 EXPECT_CALL(*this, TestCallback(IsFailure()));
634 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
Jason Glasgow14521872012-05-07 19:12:15 -0400635}
636
637// Validates Connect iterates over APNs
638TEST_F(CellularCapabilityUniversalTest, ConnectApns) {
639 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
640 SetSimpleProxy();
641 Error error;
642 DBusPropertiesMap properties;
643 capability_->apn_try_list_.clear();
644 ResultCallback callback =
645 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
646 DBus::Path bearer("/bearer0");
647
648 const char apn_name_foo[] = "foo";
649 const char apn_name_bar[] = "bar";
650 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_foo), _, _, _))
651 .WillOnce(SaveArg<2>(&connect_callback_));
652 Stringmap apn1;
653 apn1[flimflam::kApnProperty] = apn_name_foo;
654 capability_->apn_try_list_.push_back(apn1);
655 Stringmap apn2;
656 apn2[flimflam::kApnProperty] = apn_name_bar;
657 capability_->apn_try_list_.push_back(apn2);
658 capability_->FillConnectPropertyMap(&properties);
659 capability_->Connect(properties, &error, callback);
660 EXPECT_TRUE(error.IsSuccess());
661
662 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_bar), _, _, _))
663 .WillOnce(SaveArg<2>(&connect_callback_));
664 EXPECT_CALL(*service_, ClearLastGoodApn());
665 connect_callback_.Run(bearer, Error(Error::kInvalidApn));
666
667 EXPECT_CALL(*service_, SetLastGoodApn(apn2));
668 EXPECT_CALL(*this, TestCallback(IsSuccess()));
669 connect_callback_.Run(bearer, Error(Error::kSuccess));
670}
671
Jason Glasgow9f09aef2012-05-08 16:26:55 -0400672// Validates GetTypeString and AccessTechnologyToTechnologyFamily
673TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
674 const int gsm_technologies[] = {
675 MM_MODEM_ACCESS_TECHNOLOGY_LTE,
676 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
677 MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
678 MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
679 MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
680 MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
681 MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
682 MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
683 MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
684 MM_MODEM_ACCESS_TECHNOLOGY_GSM,
685 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
686 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
687 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
688 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
689 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
690 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
691 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
692 };
693 for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
694 capability_->access_technologies_ = gsm_technologies[i];
695 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
696 }
697 const int cdma_technologies[] = {
698 MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
699 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
700 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
701 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
702 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
703 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
704 };
705 for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
706 capability_->access_technologies_ = cdma_technologies[i];
707 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
708 }
709 capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
710 ASSERT_EQ(capability_->GetTypeString(), "");
711}
712
Jason Glasgowef965562012-04-10 16:12:35 -0400713} // namespace shill