blob: a8eb2073d9fa49927e675feb905041940a039007 [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
Thieu Le3d275392012-07-20 15:32:58 -0700151 void ReleaseCapabilityProxies() {
152 capability_->ReleaseProxies();
153 }
154
Jason Glasgowef965562012-04-10 16:12:35 -0400155 MOCK_METHOD1(TestCallback, void(const Error &error));
156
157 protected:
158 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400159 static const char kSimPath[];
160 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400161
162 class TestProxyFactory : public ProxyFactory {
163 public:
164 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
165 test_(test) {}
166
167 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
168 const std::string &/* path */,
169 const std::string &/* service */) {
170 return test_->modem_3gpp_proxy_.release();
171 }
172
173 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
174 const std::string &/* path */,
175 const std::string &/* service */) {
176 return test_->modem_cdma_proxy_.release();
177 }
178
179 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
180 const std::string &/* path */,
181 const std::string &/* service */) {
182 return test_->modem_proxy_.release();
183 }
184
185 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
186 const std::string &/* path */,
187 const std::string &/* service */) {
188 return test_->modem_simple_proxy_.release();
189 }
190
191 virtual mm1::SimProxyInterface *CreateSimProxy(
192 const std::string &/* path */,
193 const std::string &/* service */) {
194 return test_->sim_proxy_.release();
195 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400196 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
197 const std::string &/* path */,
198 const std::string &/* service */) {
199 return test_->properties_proxy_.release();
200 }
Jason Glasgowef965562012-04-10 16:12:35 -0400201
202 private:
203 CellularCapabilityUniversalTest *test_;
204 };
205
206 NiceMockControl control_;
207 EventDispatcher dispatcher_;
208 MockMetrics metrics_;
209 MockGLib glib_;
210 MockManager manager_;
211 CellularRefPtr cellular_;
Jason Glasgow14521872012-05-07 19:12:15 -0400212 MockCellularService *service_; // owned by cellular_
Jason Glasgowef965562012-04-10 16:12:35 -0400213 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
214 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
215 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
216 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
217 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400218 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400219 TestProxyFactory proxy_factory_;
220 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
221 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400222 mobile_provider_db *provider_db_;
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400223 DBusPropertyMapsCallback scan_callback_; // saved for testing scan operations
Jason Glasgow14521872012-05-07 19:12:15 -0400224 DBusPathCallback connect_callback_; // saved for testing connect operations
Jason Glasgowef965562012-04-10 16:12:35 -0400225};
226
227const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400228const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
229const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
230 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
231 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400232
233TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400234 // Set up mock modem properties
235 DBusPropertiesMap modem_properties;
236 string operator_name = "TestOperator";
237 string operator_code = "001400";
238
239 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
240 writer().append_uint32(kAccessTechnologies);
241
242 ::DBus::Variant v;
243 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400244 ::DBus::Struct< uint32_t, bool > quality;
245 quality._1 = 90;
246 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400247 writer << quality;
248 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
249
250 // Set up mock modem 3gpp properties
251 DBusPropertiesMap modem3gpp_properties;
252 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
253 writer().append_uint32(0);
254 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
255 writer().append_string(kImei);
256
257 EXPECT_CALL(*modem_proxy_,
258 Enable(true, _, _, CellularCapability::kTimeoutEnable))
259 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
260 EXPECT_CALL(*properties_proxy_,
261 GetAll(MM_DBUS_INTERFACE_MODEM))
262 .WillOnce(Return(modem_properties));
263 EXPECT_CALL(*properties_proxy_,
264 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
265 .WillOnce(Return(modem3gpp_properties));
Jason Glasgowef965562012-04-10 16:12:35 -0400266
267 // After setup we lose pointers to the proxies, so it is hard to set
268 // expectations.
269 SetUp();
270
271 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400272 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400273 ResultCallback callback =
274 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
275 capability_->StartModem(&error, callback);
276 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400277 EXPECT_EQ(kImei, capability_->imei_);
278 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400279}
280
281TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
282 EXPECT_CALL(*modem_proxy_,
283 Enable(true, _, _, CellularCapability::kTimeoutEnable))
284 .WillOnce(
285 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
286 EXPECT_CALL(*this, TestCallback(IsFailure()));
287 ResultCallback callback =
288 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
289 SetUp();
290
291 Error error;
292 capability_->StartModem(&error, callback);
293 EXPECT_TRUE(error.IsSuccess());
294}
295
Jason Glasgow02401cc2012-05-16 10:35:37 -0400296TEST_F(CellularCapabilityUniversalTest, StopModem) {
297 // Save pointers to proxies before they are lost by the call to InitProxies
298 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
299 SetUp();
300 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
301 capability_->InitProxies();
302
303 Error error;
304 ResultCallback callback =
305 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
306 capability_->StopModem(&error, callback);
307 EXPECT_TRUE(error.IsSuccess());
308
309 ResultCallback disable_callback;
310 EXPECT_CALL(*modem_proxy,
311 Enable(false, _, _, CellularCapability::kTimeoutEnable))
312 .WillOnce(SaveArg<2>(&disable_callback));
313 dispatcher_.DispatchPendingEvents();
314
315 EXPECT_CALL(*this, TestCallback(IsSuccess()));
316 disable_callback.Run(Error(Error::kSuccess));
317}
318
319TEST_F(CellularCapabilityUniversalTest, StopModemConnected) {
320 // Save pointers to proxies before they are lost by the call to InitProxies
321 mm1::MockModemProxy *modem_proxy = modem_proxy_.get();
322 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
323 SetUp();
324 EXPECT_CALL(*modem_proxy, set_state_changed_callback(_));
325 capability_->InitProxies();
326
327 ResultCallback disconnect_callback;
328 Error error;
329 ResultCallback callback =
330 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
331 EXPECT_CALL(*modem_simple_proxy,
332 Disconnect(::DBus::Path("/"), _, _,
333 CellularCapability::kTimeoutDefault))
334 .WillOnce(SaveArg<2>(&disconnect_callback));
Thieu Led0012052012-07-25 16:09:09 -0700335 capability_->cellular()->modem_state_ = Cellular::kModemStateConnected;
Jason Glasgow02401cc2012-05-16 10:35:37 -0400336 capability_->StopModem(&error, callback);
337 EXPECT_TRUE(error.IsSuccess());
338
339 ResultCallback disable_callback;
340 EXPECT_CALL(*modem_proxy,
341 Enable(false, _, _, CellularCapability::kTimeoutEnable))
342 .WillOnce(SaveArg<2>(&disable_callback));
343 disconnect_callback.Run(Error(Error::kSuccess));
344
345 EXPECT_CALL(*this, TestCallback(IsSuccess()));
346 disable_callback.Run(Error(Error::kSuccess));
347}
348
Thieu Le5d6864a2012-07-20 11:43:51 -0700349TEST_F(CellularCapabilityUniversalTest, DisconnectModemNoBearer) {
350 Error error;
351 ResultCallback disconnect_callback;
Thieu Le3d275392012-07-20 15:32:58 -0700352 EXPECT_CALL(*modem_simple_proxy_,
Thieu Le5d6864a2012-07-20 11:43:51 -0700353 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
354 .Times(0);
355 capability_->Disconnect(&error, disconnect_callback);
356}
357
Thieu Le3d275392012-07-20 15:32:58 -0700358TEST_F(CellularCapabilityUniversalTest, DisconnectNoProxy) {
359 Error error;
360 ResultCallback disconnect_callback;
361 capability_->bearer_path_ = "/foo";
362 EXPECT_CALL(*modem_simple_proxy_,
363 Disconnect(_, _, _, CellularCapability::kTimeoutDefault))
364 .Times(0);
365 ReleaseCapabilityProxies();
366 capability_->Disconnect(&error, disconnect_callback);
367}
368
Jason Glasgowaf583282012-04-18 15:18:22 -0400369TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
370 // Set up mock modem properties
371 DBusPropertiesMap modem_properties;
372 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
373 writer().append_uint32(kAccessTechnologies);
374 modem_properties[MM_MODEM_PROPERTY_SIM].
375 writer().append_path(kSimPath);
376
377 // Set up mock modem 3gpp properties
378 DBusPropertiesMap modem3gpp_properties;
379 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
380 writer().append_uint32(0);
381 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
382 writer().append_string(kImei);
383
384 // Set up mock modem sim properties
385 DBusPropertiesMap sim_properties;
386
387 // After setup we lose pointers to the proxies, so it is hard to set
388 // expectations.
389 EXPECT_CALL(*properties_proxy_,
390 GetAll(MM_DBUS_INTERFACE_SIM))
391 .WillOnce(Return(sim_properties));
392
393 SetUp();
394
395 EXPECT_EQ("", capability_->imei_);
396 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
397 capability_->access_technologies_);
398 EXPECT_FALSE(capability_->sim_proxy_.get());
Jason Glasgowbad114b2012-05-21 15:24:16 -0400399 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
400 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm));
Jason Glasgowaf583282012-04-18 15:18:22 -0400401 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
402 modem_properties, vector<string>());
403 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
404 EXPECT_EQ(kSimPath, capability_->sim_path_);
405 EXPECT_TRUE(capability_->sim_proxy_.get());
406
407 // Changing properties on wrong interface will not have an effect
408 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
409 modem3gpp_properties,
410 vector<string>());
411 EXPECT_EQ("", capability_->imei_);
412
413 // Changing properties on the right interface gets reflected in the
414 // capabilities object
415 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
416 modem3gpp_properties,
417 vector<string>());
418 EXPECT_EQ(kImei, capability_->imei_);
Jason Glasgowbad114b2012-05-21 15:24:16 -0400419
420 // Expect to see changes when the family changes
421 modem_properties.clear();
422 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
423 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
424 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
425 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyCdma)).
426 Times(1);
427 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
428 modem_properties,
429 vector<string>());
430 // Back to LTE
431 modem_properties.clear();
432 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
433 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE);
434 EXPECT_CALL(*device_adaptor_, EmitStringChanged(
435 flimflam::kTechnologyFamilyProperty, flimflam::kTechnologyFamilyGsm)).
436 Times(1);
437 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
438 modem_properties,
439 vector<string>());
440
441 // LTE & CDMA - the device adaptor should not be called!
442 modem_properties.clear();
443 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
444 writer().append_uint32(MM_MODEM_ACCESS_TECHNOLOGY_LTE |
445 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT);
446 EXPECT_CALL(*device_adaptor_, EmitStringChanged(_, _)).Times(0);
447 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
448 modem_properties,
449 vector<string>());
Jason Glasgowaf583282012-04-18 15:18:22 -0400450}
451
452TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
453 // Set up mock modem properties
454 DBusPropertiesMap modem_properties;
455 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
456
457 // Set up mock modem sim properties
458 const char kImsi[] = "310100000001";
459 DBusPropertiesMap sim_properties;
460 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
461
462 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
463 .WillOnce(Return(sim_properties));
464
465 // After setup we lose pointers to the proxies, so it is hard to set
466 // expectations.
467 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400468 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400469
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400470 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
471 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
472 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400473 EXPECT_FALSE(capability_->sim_proxy_.get());
474 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
475 modem_properties, vector<string>());
476 EXPECT_EQ(kSimPath, capability_->sim_path_);
477 EXPECT_TRUE(capability_->sim_proxy_.get());
478 EXPECT_EQ(kImsi, capability_->imsi_);
479
480 // Updating the SIM
481 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400482 const char kCountry[] = "us";
483 const char kCode[] = "310160";
484 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400485 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400486 const char kOperatorIdentifier[] = "310240";
487 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400488 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
489 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
490 append_string(kSimIdentifier);
491 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
492 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400493 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
494 new_properties,
495 vector<string>());
496 EXPECT_EQ(kNewImsi, capability_->imsi_);
497 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
498 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400499 EXPECT_EQ("", capability_->spn_);
500 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
501 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
502 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
503 EXPECT_EQ(4, capability_->apn_list_.size());
504
505 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
506 append_string(kOperatorName);
507 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
508 new_properties,
509 vector<string>());
510 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400511 EXPECT_EQ(kOperatorName, capability_->spn_);
512}
513
Gary Morainceba6aa2012-05-03 10:28:26 -0700514MATCHER_P(SizeIs, value, "") {
515 return static_cast<size_t>(value) == arg.size();
516}
517
518// Validates that OnScanReply does not crash with a null callback.
519TEST_F(CellularCapabilityUniversalTest, ScanWithNullCallback) {
520 Error error;
521 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
522 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeScan));
523 EXPECT_CALL(*device_adaptor_,
524 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
525 SizeIs(0)));
526 Set3gppProxy();
527 capability_->Scan(&error, ResultCallback());
528 EXPECT_TRUE(error.IsSuccess());
529}
530
Jason Glasgowcd0349c2012-05-03 23:32:15 -0400531// Validates that the scanning property is updated
532TEST_F(CellularCapabilityUniversalTest, Scan) {
533 Error error;
534
535 EXPECT_CALL(*modem_3gpp_proxy_, Scan(_, _, CellularCapability::kTimeoutScan))
536 .WillRepeatedly(SaveArg<1>(&scan_callback_));
537 EXPECT_CALL(*device_adaptor_,
538 EmitBoolChanged(flimflam::kScanningProperty, true));
539 Set3gppProxy();
540 capability_->Scan(&error, ResultCallback());
541 EXPECT_TRUE(capability_->scanning_);
542
543 // Simulate the completion of the scan with 2 networks in the results.
544 EXPECT_CALL(*device_adaptor_,
545 EmitBoolChanged(flimflam::kScanningProperty, false));
546 EXPECT_CALL(*device_adaptor_,
547 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
548 SizeIs(2)));
549 vector<DBusPropertiesMap> results;
550 const char kScanID0[] = "testID0";
551 const char kScanID1[] = "testID1";
552 results.push_back(DBusPropertiesMap());
553 results[0][CellularCapabilityUniversal::kOperatorLongProperty].
554 writer().append_string(kScanID0);
555 results.push_back(DBusPropertiesMap());
556 results[1][CellularCapabilityUniversal::kOperatorLongProperty].
557 writer().append_string(kScanID1);
558 scan_callback_.Run(results, error);
559 EXPECT_FALSE(capability_->scanning_);
560
561 // Simulate the completion of the scan with no networks in the results.
562 EXPECT_CALL(*device_adaptor_,
563 EmitBoolChanged(flimflam::kScanningProperty, true));
564 capability_->Scan(&error, ResultCallback());
565 EXPECT_TRUE(capability_->scanning_);
566 EXPECT_CALL(*device_adaptor_,
567 EmitBoolChanged(flimflam::kScanningProperty, false));
568 EXPECT_CALL(*device_adaptor_,
569 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
570 SizeIs(0)));
571 scan_callback_.Run(vector<DBusPropertiesMap>(), Error());
572 EXPECT_FALSE(capability_->scanning_);
573}
574
575// Validates expected property updates when scan fails
576TEST_F(CellularCapabilityUniversalTest, ScanFailure) {
577 Error error;
578
579 // Test immediate error
580 {
581 InSequence seq;
582 EXPECT_CALL(*modem_3gpp_proxy_,
583 Scan(_, _, CellularCapability::kTimeoutScan))
584 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::ScanError));
585 EXPECT_CALL(*modem_3gpp_proxy_,
586 Scan(_, _, CellularCapability::kTimeoutScan))
587 .WillOnce(SaveArg<1>(&scan_callback_));
588 }
589 Set3gppProxy();
590 capability_->Scan(&error, ResultCallback());
591 EXPECT_FALSE(capability_->scanning_);
592 EXPECT_TRUE(error.IsFailure());
593
594 // Initiate a scan
595 error.Populate(Error::kSuccess);
596 EXPECT_CALL(*device_adaptor_,
597 EmitBoolChanged(flimflam::kScanningProperty, true));
598 capability_->Scan(&error, ResultCallback());
599 EXPECT_TRUE(capability_->scanning_);
600 EXPECT_TRUE(error.IsSuccess());
601
602 // Validate that error is returned if Scan is called while already scanning.
603 capability_->Scan(&error, ResultCallback());
604 EXPECT_TRUE(capability_->scanning_);
605 EXPECT_TRUE(error.IsFailure());
606
607 // Validate that signals are emitted even if an error is reported.
608 capability_->found_networks_.clear();
609 capability_->found_networks_.push_back(Stringmap());
610 EXPECT_CALL(*device_adaptor_,
611 EmitBoolChanged(flimflam::kScanningProperty, false));
612 EXPECT_CALL(*device_adaptor_,
613 EmitStringmapsChanged(flimflam::kFoundNetworksProperty,
614 SizeIs(0)));
615 vector<DBusPropertiesMap> results;
616 scan_callback_.Run(results, Error(Error::kOperationFailed));
617 EXPECT_FALSE(capability_->scanning_);
618}
619
Jason Glasgow14521872012-05-07 19:12:15 -0400620// Validates expected behavior of Connect function
621TEST_F(CellularCapabilityUniversalTest, Connect) {
622 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
623 SetSimpleProxy();
624 Error error;
625 DBusPropertiesMap properties;
626 capability_->apn_try_list_.clear();
627 ResultCallback callback =
628 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
629 DBus::Path bearer("/foo");
630
631 // Test connect failures
632 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
633 .WillOnce(SaveArg<2>(&connect_callback_));
634 capability_->Connect(properties, &error, callback);
635 EXPECT_TRUE(error.IsSuccess());
636 EXPECT_CALL(*this, TestCallback(IsFailure()));
637 EXPECT_CALL(*service_, ClearLastGoodApn());
638 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
639
640 // Test connect success
641 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
642 .WillOnce(SaveArg<2>(&connect_callback_));
643 capability_->Connect(properties, &error, callback);
644 EXPECT_TRUE(error.IsSuccess());
645 EXPECT_CALL(*this, TestCallback(IsSuccess()));
646 connect_callback_.Run(bearer, Error(Error::kSuccess));
Jason Glasgow7234ec32012-05-23 16:01:21 -0400647
648 // Test connect failures without a service. Make sure that shill
649 // does not crash if the connect failed and there is no
650 // CellularService object. This can happen if the modem is enabled
651 // and then quickly disabled.
652 cellular_->service_ = NULL;
653 EXPECT_FALSE(capability_->cellular()->service());
654 EXPECT_CALL(*modem_simple_proxy, Connect(_, _, _, _))
655 .WillOnce(SaveArg<2>(&connect_callback_));
656 capability_->Connect(properties, &error, callback);
657 EXPECT_TRUE(error.IsSuccess());
658 EXPECT_CALL(*this, TestCallback(IsFailure()));
659 connect_callback_.Run(bearer, Error(Error::kOperationFailed));
Jason Glasgow14521872012-05-07 19:12:15 -0400660}
661
662// Validates Connect iterates over APNs
663TEST_F(CellularCapabilityUniversalTest, ConnectApns) {
664 mm1::MockModemSimpleProxy *modem_simple_proxy = modem_simple_proxy_.get();
665 SetSimpleProxy();
666 Error error;
667 DBusPropertiesMap properties;
668 capability_->apn_try_list_.clear();
669 ResultCallback callback =
670 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
671 DBus::Path bearer("/bearer0");
672
673 const char apn_name_foo[] = "foo";
674 const char apn_name_bar[] = "bar";
675 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_foo), _, _, _))
676 .WillOnce(SaveArg<2>(&connect_callback_));
677 Stringmap apn1;
678 apn1[flimflam::kApnProperty] = apn_name_foo;
679 capability_->apn_try_list_.push_back(apn1);
680 Stringmap apn2;
681 apn2[flimflam::kApnProperty] = apn_name_bar;
682 capability_->apn_try_list_.push_back(apn2);
683 capability_->FillConnectPropertyMap(&properties);
684 capability_->Connect(properties, &error, callback);
685 EXPECT_TRUE(error.IsSuccess());
686
687 EXPECT_CALL(*modem_simple_proxy, Connect(HasApn(apn_name_bar), _, _, _))
688 .WillOnce(SaveArg<2>(&connect_callback_));
689 EXPECT_CALL(*service_, ClearLastGoodApn());
690 connect_callback_.Run(bearer, Error(Error::kInvalidApn));
691
692 EXPECT_CALL(*service_, SetLastGoodApn(apn2));
693 EXPECT_CALL(*this, TestCallback(IsSuccess()));
694 connect_callback_.Run(bearer, Error(Error::kSuccess));
695}
696
Jason Glasgow9f09aef2012-05-08 16:26:55 -0400697// Validates GetTypeString and AccessTechnologyToTechnologyFamily
698TEST_F(CellularCapabilityUniversalTest, GetTypeString) {
699 const int gsm_technologies[] = {
700 MM_MODEM_ACCESS_TECHNOLOGY_LTE,
701 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS,
702 MM_MODEM_ACCESS_TECHNOLOGY_HSPA,
703 MM_MODEM_ACCESS_TECHNOLOGY_HSUPA,
704 MM_MODEM_ACCESS_TECHNOLOGY_HSDPA,
705 MM_MODEM_ACCESS_TECHNOLOGY_UMTS,
706 MM_MODEM_ACCESS_TECHNOLOGY_EDGE,
707 MM_MODEM_ACCESS_TECHNOLOGY_GPRS,
708 MM_MODEM_ACCESS_TECHNOLOGY_GSM_COMPACT,
709 MM_MODEM_ACCESS_TECHNOLOGY_GSM,
710 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
711 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
712 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
713 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
714 MM_MODEM_ACCESS_TECHNOLOGY_LTE | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
715 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
716 MM_MODEM_ACCESS_TECHNOLOGY_GSM | MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
717 };
718 for(size_t i = 0; i < arraysize(gsm_technologies); ++i) {
719 capability_->access_technologies_ = gsm_technologies[i];
720 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyGsm);
721 }
722 const int cdma_technologies[] = {
723 MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
724 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA,
725 MM_MODEM_ACCESS_TECHNOLOGY_EVDOA | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
726 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB,
727 MM_MODEM_ACCESS_TECHNOLOGY_EVDOB | MM_MODEM_ACCESS_TECHNOLOGY_EVDO0,
728 MM_MODEM_ACCESS_TECHNOLOGY_1XRTT,
729 };
730 for(size_t i = 0; i < arraysize(cdma_technologies); ++i) {
731 capability_->access_technologies_ = cdma_technologies[i];
732 ASSERT_EQ(capability_->GetTypeString(), flimflam::kTechnologyFamilyCdma);
733 }
734 capability_->access_technologies_ = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN;
735 ASSERT_EQ(capability_->GetTypeString(), "");
736}
737
Jason Glasgowef965562012-04-10 16:12:35 -0400738} // namespace shill