blob: fd63af46af469a7503a5a4ede1532a6c99a1cc18 [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 Glasgowaf583282012-04-18 15:18:22 -040022#include "shill/mock_dbus_properties_proxy.h"
Jason Glasgowef965562012-04-10 16:12:35 -040023#include "shill/mock_glib.h"
24#include "shill/mock_manager.h"
25#include "shill/mock_metrics.h"
26#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
27#include "shill/mock_mm1_modem_modemcdma_proxy.h"
28#include "shill/mock_mm1_modem_proxy.h"
29#include "shill/mock_mm1_modem_simple_proxy.h"
30#include "shill/mock_mm1_sim_proxy.h"
31#include "shill/mock_profile.h"
32#include "shill/mock_rtnl_handler.h"
33#include "shill/nice_mock_control.h"
34#include "shill/proxy_factory.h"
35
36using base::Bind;
37using base::Unretained;
38using std::string;
Nathan Williams4b7c2a82012-04-13 15:19:47 -040039using std::vector;
Jason Glasgowef965562012-04-10 16:12:35 -040040using testing::InSequence;
41using testing::NiceMock;
42using testing::Return;
43using testing::_;
44
45namespace shill {
46
47MATCHER(IsSuccess, "") {
48 return arg.IsSuccess();
49}
50MATCHER(IsFailure, "") {
51 return arg.IsFailure();
52}
53
54class CellularCapabilityUniversalTest : public testing::Test {
55 public:
56 CellularCapabilityUniversalTest()
57 : manager_(&control_, &dispatcher_, &metrics_, &glib_),
58 cellular_(new Cellular(&control_,
59 &dispatcher_,
60 NULL,
61 &manager_,
62 "",
63 "",
64 0,
65 Cellular::kTypeUniversal,
66 "",
67 "",
68 NULL)),
69 modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
70 modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
71 modem_proxy_(new mm1::MockModemProxy()),
72 modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
73 sim_proxy_(new mm1::MockSimProxy()),
Jason Glasgowaf583282012-04-18 15:18:22 -040074 properties_proxy_(new MockDBusPropertiesProxy()),
Jason Glasgowef965562012-04-10 16:12:35 -040075 proxy_factory_(this),
76 capability_(NULL),
77 device_adaptor_(NULL) {}
78
79 virtual ~CellularCapabilityUniversalTest() {
80 cellular_->service_ = NULL;
81 capability_ = NULL;
82 device_adaptor_ = NULL;
83 }
84
85 virtual void SetUp() {
86 capability_ = dynamic_cast<CellularCapabilityUniversal *>(
87 cellular_->capability_.get());
88 capability_->proxy_factory_ = &proxy_factory_;
89 device_adaptor_ =
90 dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
91 }
92
93 virtual void TearDown() {
94 capability_->proxy_factory_ = NULL;
95 }
96
97 void InvokeEnable(bool enable, Error *error,
98 const ResultCallback &callback, int timeout) {
99 callback.Run(Error());
100 }
101 void InvokeEnableFail(bool enable, Error *error,
102 const ResultCallback &callback, int timeout) {
103 callback.Run(Error(Error::kOperationFailed));
104 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400105 void InvokeRegister(const string &operator_id, Error *error,
106 const ResultCallback &callback, int timeout) {
107 callback.Run(Error());
108 }
109
Jason Glasgowef965562012-04-10 16:12:35 -0400110
111 MOCK_METHOD1(TestCallback, void(const Error &error));
112
113 protected:
114 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400115 static const char kSimPath[];
116 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400117
118 class TestProxyFactory : public ProxyFactory {
119 public:
120 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
121 test_(test) {}
122
123 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
124 const std::string &/* path */,
125 const std::string &/* service */) {
126 return test_->modem_3gpp_proxy_.release();
127 }
128
129 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
130 const std::string &/* path */,
131 const std::string &/* service */) {
132 return test_->modem_cdma_proxy_.release();
133 }
134
135 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
136 const std::string &/* path */,
137 const std::string &/* service */) {
138 return test_->modem_proxy_.release();
139 }
140
141 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
142 const std::string &/* path */,
143 const std::string &/* service */) {
144 return test_->modem_simple_proxy_.release();
145 }
146
147 virtual mm1::SimProxyInterface *CreateSimProxy(
148 const std::string &/* path */,
149 const std::string &/* service */) {
150 return test_->sim_proxy_.release();
151 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400152 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
153 const std::string &/* path */,
154 const std::string &/* service */) {
155 return test_->properties_proxy_.release();
156 }
Jason Glasgowef965562012-04-10 16:12:35 -0400157
158 private:
159 CellularCapabilityUniversalTest *test_;
160 };
161
162 NiceMockControl control_;
163 EventDispatcher dispatcher_;
164 MockMetrics metrics_;
165 MockGLib glib_;
166 MockManager manager_;
167 CellularRefPtr cellular_;
168 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
169 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
170 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
171 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
172 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400173 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400174 TestProxyFactory proxy_factory_;
175 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
176 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
177};
178
179const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400180const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
181const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
182 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
183 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400184
185TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400186 // Set up mock modem properties
187 DBusPropertiesMap modem_properties;
188 string operator_name = "TestOperator";
189 string operator_code = "001400";
190
191 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
192 writer().append_uint32(kAccessTechnologies);
193
194 ::DBus::Variant v;
195 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400196 ::DBus::Struct< uint32_t, bool > quality;
197 quality._1 = 90;
198 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400199 writer << quality;
200 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
201
202 // Set up mock modem 3gpp properties
203 DBusPropertiesMap modem3gpp_properties;
204 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
205 writer().append_uint32(0);
206 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
207 writer().append_string(kImei);
208
209 EXPECT_CALL(*modem_proxy_,
210 Enable(true, _, _, CellularCapability::kTimeoutEnable))
211 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
212 EXPECT_CALL(*properties_proxy_,
213 GetAll(MM_DBUS_INTERFACE_MODEM))
214 .WillOnce(Return(modem_properties));
215 EXPECT_CALL(*properties_proxy_,
216 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
217 .WillOnce(Return(modem3gpp_properties));
218 EXPECT_CALL(*modem_3gpp_proxy_,
219 Register(_, _, _, _))
220 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeRegister));
Jason Glasgowef965562012-04-10 16:12:35 -0400221 EXPECT_CALL(*modem_proxy_, SignalQuality()).WillOnce(Return(quality));
Jason Glasgowef965562012-04-10 16:12:35 -0400222 EXPECT_CALL(*modem_3gpp_proxy_, RegistrationState())
Jason Glasgowaf583282012-04-18 15:18:22 -0400223 .WillOnce(Return(MM_MODEM_3GPP_REGISTRATION_STATE_HOME));
224 EXPECT_CALL(*modem_3gpp_proxy_, OperatorName())
225 .WillOnce(Return(operator_name));
226 EXPECT_CALL(*modem_3gpp_proxy_, OperatorCode())
227 .WillOnce(Return(operator_code));
Jason Glasgowef965562012-04-10 16:12:35 -0400228
229 // After setup we lose pointers to the proxies, so it is hard to set
230 // expectations.
231 SetUp();
232
233 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400234 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400235 ResultCallback callback =
236 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
237 capability_->StartModem(&error, callback);
238 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400239 EXPECT_EQ(kImei, capability_->imei_);
240 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400241}
242
243TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
244 EXPECT_CALL(*modem_proxy_,
245 Enable(true, _, _, CellularCapability::kTimeoutEnable))
246 .WillOnce(
247 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
248 EXPECT_CALL(*this, TestCallback(IsFailure()));
249 ResultCallback callback =
250 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
251 SetUp();
252
253 Error error;
254 capability_->StartModem(&error, callback);
255 EXPECT_TRUE(error.IsSuccess());
256}
257
Jason Glasgowaf583282012-04-18 15:18:22 -0400258TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
259 // Set up mock modem properties
260 DBusPropertiesMap modem_properties;
261 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
262 writer().append_uint32(kAccessTechnologies);
263 modem_properties[MM_MODEM_PROPERTY_SIM].
264 writer().append_path(kSimPath);
265
266 // Set up mock modem 3gpp properties
267 DBusPropertiesMap modem3gpp_properties;
268 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
269 writer().append_uint32(0);
270 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
271 writer().append_string(kImei);
272
273 // Set up mock modem sim properties
274 DBusPropertiesMap sim_properties;
275
276 // After setup we lose pointers to the proxies, so it is hard to set
277 // expectations.
278 EXPECT_CALL(*properties_proxy_,
279 GetAll(MM_DBUS_INTERFACE_SIM))
280 .WillOnce(Return(sim_properties));
281
282 SetUp();
283
284 EXPECT_EQ("", capability_->imei_);
285 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
286 capability_->access_technologies_);
287 EXPECT_FALSE(capability_->sim_proxy_.get());
288 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
289 modem_properties, vector<string>());
290 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
291 EXPECT_EQ(kSimPath, capability_->sim_path_);
292 EXPECT_TRUE(capability_->sim_proxy_.get());
293
294 // Changing properties on wrong interface will not have an effect
295 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
296 modem3gpp_properties,
297 vector<string>());
298 EXPECT_EQ("", capability_->imei_);
299
300 // Changing properties on the right interface gets reflected in the
301 // capabilities object
302 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
303 modem3gpp_properties,
304 vector<string>());
305 EXPECT_EQ(kImei, capability_->imei_);
306}
307
308TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
309 // Set up mock modem properties
310 DBusPropertiesMap modem_properties;
311 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
312
313 // Set up mock modem sim properties
314 const char kImsi[] = "310100000001";
315 DBusPropertiesMap sim_properties;
316 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
317
318 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
319 .WillOnce(Return(sim_properties));
320
321 // After setup we lose pointers to the proxies, so it is hard to set
322 // expectations.
323 SetUp();
324
325 EXPECT_FALSE(capability_->sim_proxy_.get());
326 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
327 modem_properties, vector<string>());
328 EXPECT_EQ(kSimPath, capability_->sim_path_);
329 EXPECT_TRUE(capability_->sim_proxy_.get());
330 EXPECT_EQ(kImsi, capability_->imsi_);
331
332 // Updating the SIM
333 DBusPropertiesMap new_properties;
334 const char kNewImsi[] = "123123123";
335 const char kSimIdentifier[] = "9999888";
336 const char kOperatorIdentifier[] = "410";
337 const char kOperatorName[] = "new operator";
338 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
339 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
340 append_string(kSimIdentifier);
341 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
342 append_string(kOperatorIdentifier);
343 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
344 append_string(kOperatorName);
345 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
346 new_properties,
347 vector<string>());
348 EXPECT_EQ(kNewImsi, capability_->imsi_);
349 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
350 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
351 EXPECT_EQ(kOperatorName, capability_->spn_);
352}
353
Jason Glasgowef965562012-04-10 16:12:35 -0400354} // namespace shill