blob: cbec9ad599723d68511567fd50df9250f3705a27 [file] [log] [blame]
Darin Petkovac635a82012-01-10 16:51:58 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkovb72cf402011-11-22 14:51:39 +01002// 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_service.h"
6
7#include <chromeos/dbus/service_constants.h>
8#include <gtest/gtest.h>
Christopher Wiley1582bdd2012-11-15 11:31:14 -08009#include <mm/mm-modem.h>
Darin Petkovb72cf402011-11-22 14:51:39 +010010
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050011#include "shill/cellular_capability.h"
Ben Chan3ecdf822012-08-06 12:29:23 -070012#include "shill/cellular_capability_cdma.h"
Darin Petkovb72cf402011-11-22 14:51:39 +010013#include "shill/mock_adaptors.h"
Ben Chan96580442012-09-19 16:19:39 -070014#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080015#include "shill/mock_metrics.h"
Eric Shienbroodc7073302012-04-03 14:41:44 -040016#include "shill/mock_profile.h"
Ben Chan19f83972012-10-03 23:25:56 -070017#include "shill/mock_store.h"
Ben Chan3ecdf822012-08-06 12:29:23 -070018#include "shill/nice_mock_control.h"
19#include "shill/proxy_factory.h"
Darin Petkovb72cf402011-11-22 14:51:39 +010020
Darin Petkov31332412012-01-28 01:50:02 +010021using std::string;
Darin Petkov9cb02682012-01-28 00:17:38 +010022using testing::_;
Eric Shienbroodc7073302012-04-03 14:41:44 -040023using testing::InSequence;
Darin Petkovb72cf402011-11-22 14:51:39 +010024using testing::NiceMock;
Ben Chan96580442012-09-19 16:19:39 -070025using testing::Return;
Darin Petkovb72cf402011-11-22 14:51:39 +010026
27namespace shill {
28
29class CellularServiceTest : public testing::Test {
30 public:
31 CellularServiceTest()
Ben Chan96580442012-09-19 16:19:39 -070032 : manager_(&control_, &dispatcher_, &metrics_, NULL),
33 device_(new Cellular(&control_,
Darin Petkovac635a82012-01-10 16:51:58 +010034 NULL,
Thieu Le3426c8f2012-01-11 17:35:11 -080035 &metrics_,
Ben Chan96580442012-09-19 16:19:39 -070036 &manager_,
Darin Petkovac635a82012-01-10 16:51:58 +010037 "usb0",
Darin Petkov31332412012-01-28 01:50:02 +010038 kAddress,
Darin Petkovac635a82012-01-10 16:51:58 +010039 3,
Ben Chan3ecdf822012-08-06 12:29:23 -070040 Cellular::kTypeCDMA,
Darin Petkovac635a82012-01-10 16:51:58 +010041 "",
42 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040043 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070044 NULL,
Ben Chan62028b22012-11-05 11:20:02 -080045 NULL,
Ben Chan3ecdf822012-08-06 12:29:23 -070046 ProxyFactory::GetInstance())),
Ben Chan96580442012-09-19 16:19:39 -070047 service_(new CellularService(&control_, NULL, &metrics_, &manager_,
Thieu Le3426c8f2012-01-11 17:35:11 -080048 device_)),
Darin Petkovb72cf402011-11-22 14:51:39 +010049 adaptor_(NULL) {}
50
51 virtual ~CellularServiceTest() {
52 adaptor_ = NULL;
53 }
54
55 virtual void SetUp() {
56 adaptor_ =
57 dynamic_cast<NiceMock<ServiceMockAdaptor> *>(service_->adaptor());
58 }
59
Ben Chan3ecdf822012-08-06 12:29:23 -070060 CellularCapabilityCDMA *GetCapabilityCDMA() {
61 return dynamic_cast<CellularCapabilityCDMA *>(device_->capability_.get());
Jason Glasgow82f9ab32012-04-04 14:27:19 -040062 }
63
Darin Petkovb72cf402011-11-22 14:51:39 +010064 protected:
Darin Petkov31332412012-01-28 01:50:02 +010065 static const char kAddress[];
66
Darin Petkov457728b2013-01-09 09:49:08 +010067 string GetFriendlyName() const { return service_->friendly_name(); }
68
Darin Petkovb72cf402011-11-22 14:51:39 +010069 NiceMockControl control_;
Ben Chan96580442012-09-19 16:19:39 -070070 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -080071 MockMetrics metrics_;
Ben Chan96580442012-09-19 16:19:39 -070072 MockManager manager_;
Darin Petkovac635a82012-01-10 16:51:58 +010073 CellularRefPtr device_;
Darin Petkovb72cf402011-11-22 14:51:39 +010074 CellularServiceRefPtr service_;
75 NiceMock<ServiceMockAdaptor> *adaptor_; // Owned by |service_|.
76};
77
Darin Petkov31332412012-01-28 01:50:02 +010078const char CellularServiceTest::kAddress[] = "000102030405";
79
Thieu Le9fdf1372012-05-14 15:20:48 -070080TEST_F(CellularServiceTest, Constructor) {
81 EXPECT_TRUE(service_->connectable());
82}
83
Ben Chan96580442012-09-19 16:19:39 -070084TEST_F(CellularServiceTest, SetActivationState) {
85 {
86 InSequence call_sequence;
87 EXPECT_CALL(*adaptor_, EmitStringChanged(
88 flimflam::kActivationStateProperty,
89 flimflam::kActivationStateNotActivated));
90 EXPECT_CALL(*adaptor_, EmitBoolChanged(
91 flimflam::kConnectableProperty, false));
92 EXPECT_CALL(*adaptor_, EmitStringChanged(
93 flimflam::kActivationStateProperty,
94 flimflam::kActivationStateActivating));
95 EXPECT_CALL(*adaptor_, EmitBoolChanged(
96 flimflam::kConnectableProperty, true));
97 EXPECT_CALL(*adaptor_, EmitStringChanged(
98 flimflam::kActivationStateProperty,
99 flimflam::kActivationStatePartiallyActivated));
100 EXPECT_CALL(*adaptor_, EmitStringChanged(
101 flimflam::kActivationStateProperty,
102 flimflam::kActivationStateActivated));
103 EXPECT_CALL(*adaptor_, EmitStringChanged(
104 flimflam::kActivationStateProperty,
105 flimflam::kActivationStateNotActivated));
106 EXPECT_CALL(*adaptor_, EmitBoolChanged(
107 flimflam::kConnectableProperty, false));
108 }
109 EXPECT_CALL(manager_, HasService(_)).WillRepeatedly(Return(false));
110
111 EXPECT_TRUE(service_->activation_state().empty());
112 EXPECT_TRUE(service_->connectable());
113
114 service_->SetActivationState(flimflam::kActivationStateNotActivated);
115 EXPECT_EQ(flimflam::kActivationStateNotActivated,
116 service_->activation_state());
117 EXPECT_FALSE(service_->connectable());
118
119 service_->SetActivationState(flimflam::kActivationStateActivating);
120 EXPECT_EQ(flimflam::kActivationStateActivating, service_->activation_state());
121 EXPECT_TRUE(service_->connectable());
122
123 service_->SetActivationState(flimflam::kActivationStatePartiallyActivated);
124 EXPECT_EQ(flimflam::kActivationStatePartiallyActivated,
125 service_->activation_state());
126 EXPECT_TRUE(service_->connectable());
127
128 service_->SetActivationState(flimflam::kActivationStateActivated);
129 EXPECT_EQ(flimflam::kActivationStateActivated, service_->activation_state());
130 EXPECT_TRUE(service_->connectable());
131
132 service_->SetActivationState(flimflam::kActivationStateNotActivated);
133 EXPECT_EQ(flimflam::kActivationStateNotActivated,
134 service_->activation_state());
135 EXPECT_FALSE(service_->connectable());
136}
137
Darin Petkovb72cf402011-11-22 14:51:39 +0100138TEST_F(CellularServiceTest, SetNetworkTechnology) {
139 EXPECT_CALL(*adaptor_, EmitStringChanged(flimflam::kNetworkTechnologyProperty,
140 flimflam::kNetworkTechnologyUmts));
141 EXPECT_TRUE(service_->network_technology().empty());
142 service_->SetNetworkTechnology(flimflam::kNetworkTechnologyUmts);
143 EXPECT_EQ(flimflam::kNetworkTechnologyUmts, service_->network_technology());
144 service_->SetNetworkTechnology(flimflam::kNetworkTechnologyUmts);
145}
146
147TEST_F(CellularServiceTest, SetRoamingState) {
148 EXPECT_CALL(*adaptor_, EmitStringChanged(flimflam::kRoamingStateProperty,
149 flimflam::kRoamingStateHome));
150 EXPECT_TRUE(service_->roaming_state().empty());
151 service_->SetRoamingState(flimflam::kRoamingStateHome);
152 EXPECT_EQ(flimflam::kRoamingStateHome, service_->roaming_state());
153 service_->SetRoamingState(flimflam::kRoamingStateHome);
154}
155
Darin Petkovac635a82012-01-10 16:51:58 +0100156TEST_F(CellularServiceTest, FriendlyName) {
157 static const char kCarrier[] = "Cellular Carrier";
Ben Chan3ecdf822012-08-06 12:29:23 -0700158 GetCapabilityCDMA()->carrier_ = kCarrier;
Thieu Le3426c8f2012-01-11 17:35:11 -0800159 service_ = new CellularService(&control_, NULL, &metrics_, NULL, device_);
Darin Petkov457728b2013-01-09 09:49:08 +0100160 EXPECT_EQ(kCarrier, GetFriendlyName());
Darin Petkovac635a82012-01-10 16:51:58 +0100161}
162
Darin Petkov31332412012-01-28 01:50:02 +0100163TEST_F(CellularServiceTest, SetStorageIdentifier) {
Darin Petkovdd3e8662012-02-03 13:16:20 +0100164 EXPECT_EQ(string(flimflam::kTypeCellular) + "_" +
Darin Petkov457728b2013-01-09 09:49:08 +0100165 kAddress + "_" + GetFriendlyName(),
Darin Petkov31332412012-01-28 01:50:02 +0100166 service_->GetStorageIdentifier());
167 service_->SetStorageIdentifier("a b c");
168 EXPECT_EQ("a_b_c", service_->GetStorageIdentifier());
169}
170
Darin Petkov9cb02682012-01-28 00:17:38 +0100171TEST_F(CellularServiceTest, SetServingOperator) {
172 EXPECT_CALL(*adaptor_,
173 EmitStringmapChanged(flimflam::kServingOperatorProperty, _));
174 static const char kCode[] = "123456";
175 static const char kName[] = "Some Cellular Operator";
176 Cellular::Operator oper;
177 service_->SetServingOperator(oper);
178 oper.SetCode(kCode);
179 oper.SetName(kName);
180 service_->SetServingOperator(oper);
181 EXPECT_EQ(kCode, service_->serving_operator().GetCode());
182 EXPECT_EQ(kName, service_->serving_operator().GetName());
183 service_->SetServingOperator(oper);
184}
185
Darin Petkov381928f2012-02-02 23:00:12 +0100186TEST_F(CellularServiceTest, SetOLP) {
187 EXPECT_CALL(*adaptor_,
188 EmitStringmapChanged(flimflam::kPaymentPortalProperty, _));
189 static const char kURL[] = "payment.url";
190 static const char kMethod[] = "GET";
191 CellularService::OLP olp;
192 service_->SetOLP(olp);
193 olp.SetURL(kURL);
194 olp.SetMethod(kMethod);
195 service_->SetOLP(olp);
196 EXPECT_EQ(kURL, service_->olp().GetURL());
197 EXPECT_EQ(kMethod, service_->olp().GetMethod());
198 service_->SetOLP(olp);
199}
200
201TEST_F(CellularServiceTest, SetUsageURL) {
202 static const char kUsageURL[] = "usage.url";
203 EXPECT_CALL(*adaptor_, EmitStringChanged(flimflam::kUsageURLProperty,
204 kUsageURL));
205 EXPECT_TRUE(service_->usage_url().empty());
206 service_->SetUsageURL(kUsageURL);
207 EXPECT_EQ(kUsageURL, service_->usage_url());
208 service_->SetUsageURL(kUsageURL);
209}
210
Eric Shienbroodc7073302012-04-03 14:41:44 -0400211TEST_F(CellularServiceTest, SetApn) {
212 static const char kApn[] = "TheAPN";
213 static const char kUsername[] = "commander.data";
214 ProfileRefPtr profile(new NiceMock<MockProfile>(
215 &control_, reinterpret_cast<Manager *>(NULL)));
216 service_->set_profile(profile);
217 Error error;
218 Stringmap testapn;
219 testapn[flimflam::kApnProperty] = kApn;
220 testapn[flimflam::kApnUsernameProperty] = kUsername;
221 {
222 InSequence seq;
223 EXPECT_CALL(*adaptor_,
224 EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
225 _));
226 EXPECT_CALL(*adaptor_,
227 EmitStringmapChanged(flimflam::kCellularApnProperty, _));
228 }
229 service_->SetApn(testapn, &error);
230 EXPECT_TRUE(error.IsSuccess());
231 Stringmap resultapn = service_->GetApn(&error);
232 EXPECT_TRUE(error.IsSuccess());
233 EXPECT_EQ(2, resultapn.size());
234 Stringmap::const_iterator it = resultapn.find(flimflam::kApnProperty);
235 EXPECT_TRUE(it != resultapn.end() && it->second == kApn);
236 it = resultapn.find(flimflam::kApnUsernameProperty);
237 EXPECT_TRUE(it != resultapn.end() && it->second == kUsername);
238 EXPECT_FALSE(service_->GetUserSpecifiedApn() == NULL);
239}
240
241TEST_F(CellularServiceTest, ClearApn) {
242 static const char kApn[] = "TheAPN";
243 static const char kUsername[] = "commander.data";
244 ProfileRefPtr profile(new NiceMock<MockProfile>(
245 &control_, reinterpret_cast<Manager *>(NULL)));
246 service_->set_profile(profile);
247 Error error;
248 // Set up an APN to make sure that it later gets cleared.
249 Stringmap testapn;
250 testapn[flimflam::kApnProperty] = kApn;
251 testapn[flimflam::kApnUsernameProperty] = kUsername;
252 {
253 InSequence seq;
254 EXPECT_CALL(*adaptor_,
255 EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
256 _));
257 EXPECT_CALL(*adaptor_,
258 EmitStringmapChanged(flimflam::kCellularApnProperty, _));
259 }
260 service_->SetApn(testapn, &error);
261 Stringmap resultapn = service_->GetApn(&error);
262 ASSERT_TRUE(error.IsSuccess());
263 ASSERT_EQ(2, service_->GetApn(&error).size());
264
265 Stringmap emptyapn;
266 EXPECT_CALL(*adaptor_,
267 EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
268 _)).Times(0);
269 EXPECT_CALL(*adaptor_,
270 EmitStringmapChanged(flimflam::kCellularApnProperty, _)).Times(1);
271 service_->SetApn(emptyapn, &error);
272 EXPECT_TRUE(error.IsSuccess());
273 resultapn = service_->GetApn(&error);
274 EXPECT_TRUE(resultapn.empty());
275 EXPECT_TRUE(service_->GetUserSpecifiedApn() == NULL);
276}
277
278TEST_F(CellularServiceTest, LastGoodApn) {
279 static const char kApn[] = "TheAPN";
280 static const char kUsername[] = "commander.data";
281 ProfileRefPtr profile(new NiceMock<MockProfile>(
282 &control_, reinterpret_cast<Manager *>(NULL)));
283 service_->set_profile(profile);
284 Stringmap testapn;
285 testapn[flimflam::kApnProperty] = kApn;
286 testapn[flimflam::kApnUsernameProperty] = kUsername;
287 EXPECT_CALL(*adaptor_,
288 EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty, _));
289 service_->SetLastGoodApn(testapn);
290 Stringmap *resultapn = service_->GetLastGoodApn();
291 EXPECT_FALSE(resultapn == NULL);
292 EXPECT_EQ(2, resultapn->size());
293 Stringmap::const_iterator it = resultapn->find(flimflam::kApnProperty);
294 EXPECT_TRUE(it != resultapn->end() && it->second == kApn);
295 it = resultapn->find(flimflam::kApnUsernameProperty);
296 EXPECT_TRUE(it != resultapn->end() && it->second == kUsername);
297 // Now set the user-specified APN, and check that LastGoodApn got
298 // cleared.
299 Stringmap userapn;
300 userapn[flimflam::kApnProperty] = kApn;
301 userapn[flimflam::kApnUsernameProperty] = kUsername;
302 {
303 InSequence seq;
304 EXPECT_CALL(*adaptor_,
305 EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
306 _));
307 EXPECT_CALL(*adaptor_,
308 EmitStringmapChanged(flimflam::kCellularApnProperty, _));
309 }
310 Error error;
311 service_->SetApn(userapn, &error);
312 EXPECT_TRUE(service_->GetLastGoodApn() == NULL);
313}
314
Ben Chan19f83972012-10-03 23:25:56 -0700315TEST_F(CellularServiceTest, IsAutoConnectable) {
316 const char *reason = NULL;
317
318 // Auto-connect should be suppressed if the device is not running.
319 device_->running_ = false;
320 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
321 EXPECT_STREQ(CellularService::kAutoConnDeviceDisabled, reason);
322
323 device_->running_ = true;
324
Christopher Wiley1582bdd2012-11-15 11:31:14 -0800325 // If we're waiting on a disconnect before an activation, don't auto-connect.
326 GetCapabilityCDMA()->activation_starting_ = true;
327 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
328
329 // If we're waiting on an activation, also don't auto-connect.
330 GetCapabilityCDMA()->activation_starting_ = false;
331 GetCapabilityCDMA()->activation_state_ =
332 MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING;
333 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
334
335 // But other activation states are fine.
336 GetCapabilityCDMA()->activation_state_ =
337 MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED;
338 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
339 GetCapabilityCDMA()->activation_state_ =
340 MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED;
341 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
342 GetCapabilityCDMA()->activation_state_ =
343 MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED;
344 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
345
Ben Chan19f83972012-10-03 23:25:56 -0700346 // The following test cases are copied from ServiceTest.IsAutoConnectable
347
348 service_->set_connectable(true);
349 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
350
351 // We should not auto-connect to a Service that a user has
352 // deliberately disconnected.
353 Error error;
354 service_->UserInitiatedDisconnect(&error);
355 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
356 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
357
358 // But if the Service is reloaded, it is eligible for auto-connect
359 // again.
360 NiceMock<MockStore> storage;
361 EXPECT_CALL(storage, ContainsGroup(service_->GetStorageIdentifier()))
362 .WillOnce(Return(true));
363 EXPECT_TRUE(service_->Load(&storage));
364 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
365
366 // A non-user initiated Disconnect doesn't change anything.
367 service_->Disconnect(&error);
368 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
369
370 // A resume also re-enables auto-connect.
371 service_->UserInitiatedDisconnect(&error);
372 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
373 service_->OnAfterResume();
374 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
375
376 service_->SetState(Service::kStateConnected);
377 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
378 EXPECT_STREQ(Service::kAutoConnConnected, reason);
379
380 service_->SetState(Service::kStateAssociating);
381 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
382 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
383}
384
Darin Petkovb72cf402011-11-22 14:51:39 +0100385} // namespace shill