blob: 32e528b18715be929bd46bddbffbdc89a80d48cc [file] [log] [blame]
Paul Stewartd8ad3c42012-01-09 12:39:38 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07002// 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/service.h"
6
7#include <map>
8#include <string>
9#include <vector>
10
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include <base/bind.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070012#include <chromeos/dbus/service_constants.h>
mukesh agrawal1830fa12011-09-26 14:31:40 -070013#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070014#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
17#include "shill/dbus_adaptor.h"
18#include "shill/ethernet_service.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070020#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070021#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070022#include "shill/mock_control.h"
Paul Stewart10241e32012-04-23 18:15:06 -070023#include "shill/mock_connection.h"
24#include "shill/mock_device_info.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070025#include "shill/mock_manager.h"
Paul Stewartff14b022012-04-24 20:06:23 -070026#include "shill/mock_profile.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070027#include "shill/mock_store.h"
Paul Stewart8e7e4592012-04-29 09:47:48 -070028#include "shill/property_store_inspector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070029#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070030#include "shill/service_under_test.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070031
Eric Shienbrood9a245532012-03-07 14:20:39 -050032using base::Bind;
33using base::Unretained;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070034using std::map;
35using std::string;
36using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070037using testing::_;
38using testing::AtLeast;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080039using testing::DoAll;
Paul Stewart81426132012-05-16 10:05:10 -070040using testing::Mock;
Darin Petkovba40dd32011-07-11 20:06:39 -070041using testing::NiceMock;
42using testing::Return;
Paul Stewart10241e32012-04-23 18:15:06 -070043using testing::ReturnRef;
Darin Petkovba40dd32011-07-11 20:06:39 -070044using testing::StrictMock;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080045using testing::SetArgumentPointee;
Darin Petkovba40dd32011-07-11 20:06:39 -070046using testing::Test;
Paul Stewart9f32d192012-01-30 20:37:50 -080047using testing::Values;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070048
49namespace shill {
50
51class ServiceTest : public PropertyStoreTest {
52 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070053 ServiceTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080054 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
Chris Masone2176a882011-09-14 22:29:15 -070055 service_(new ServiceUnderTest(control_interface(),
56 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080057 metrics(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070058 &mock_manager_)),
Chris Masone9d779932011-08-25 16:33:41 -070059 storage_id_(ServiceUnderTest::kStorageId) {
60 }
Chris Masoneb925cc82011-06-22 15:39:57 -070061
Chris Masone3bd3c8c2011-06-13 08:20:26 -070062 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -070063
Eric Shienbrood9a245532012-03-07 14:20:39 -050064 MOCK_METHOD1(TestCallback, void(const Error &error));
65
Chris Masoneb925cc82011-06-22 15:39:57 -070066 protected:
Eric Shienbrood9a245532012-03-07 14:20:39 -050067
Paul Stewart03dba0b2011-08-22 16:32:45 -070068 MockManager mock_manager_;
69 scoped_refptr<ServiceUnderTest> service_;
Chris Masone34af2182011-08-22 11:59:36 -070070 string storage_id_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070071};
72
Darin Petkovba40dd32011-07-11 20:06:39 -070073TEST_F(ServiceTest, Constructor) {
74 EXPECT_TRUE(service_->save_credentials_);
75 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -040076 EXPECT_EQ(Service::kStateIdle, service_->state());
Darin Petkovba40dd32011-07-11 20:06:39 -070077}
78
Chris Masonea8a2c252011-06-27 22:16:30 -070079TEST_F(ServiceTest, GetProperties) {
80 map<string, ::DBus::Variant> props;
81 Error error(Error::kInvalidProperty, "");
82 {
83 ::DBus::Error dbus_error;
Paul Stewartd215af62012-04-24 23:25:50 -070084 string expected("true");
mukesh agrawalde29fa82011-09-16 16:16:36 -070085 service_->mutable_store()->SetStringProperty(flimflam::kCheckPortalProperty,
86 expected,
87 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070088 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070089 ASSERT_FALSE(props.find(flimflam::kCheckPortalProperty) == props.end());
90 EXPECT_EQ(props[flimflam::kCheckPortalProperty].reader().get_string(),
91 expected);
92 }
93 {
94 ::DBus::Error dbus_error;
95 bool expected = true;
Thieu Le284fe792012-01-31 17:53:19 -080096 service_->set_favorite(true);
mukesh agrawalde29fa82011-09-16 16:16:36 -070097 service_->mutable_store()->SetBoolProperty(flimflam::kAutoConnectProperty,
98 expected,
99 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700100 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700101 ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
102 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
103 expected);
104 }
105 {
106 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700107 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700108 ASSERT_FALSE(props.find(flimflam::kConnectableProperty) == props.end());
109 EXPECT_EQ(props[flimflam::kConnectableProperty].reader().get_bool(), false);
110 }
111 {
112 ::DBus::Error dbus_error;
113 int32 expected = 127;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700114 service_->mutable_store()->SetInt32Property(flimflam::kPriorityProperty,
115 expected,
116 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700117 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700118 ASSERT_FALSE(props.find(flimflam::kPriorityProperty) == props.end());
119 EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
120 expected);
121 }
Chris Masone95207da2011-06-29 16:50:49 -0700122 {
123 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700124 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masone95207da2011-06-29 16:50:49 -0700125 ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
Jason Glasgowacdc11f2012-03-30 14:12:22 -0400126 EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_path(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700127 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700128 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700129}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700130
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800131TEST_F(ServiceTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700132 {
133 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800134 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
135 flimflam::kSaveCredentialsProperty,
136 PropertyStoreTest::kBoolV,
137 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700138 }
139 {
140 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800141 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
142 flimflam::kPriorityProperty,
143 PropertyStoreTest::kInt32V,
144 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700145 }
146 {
147 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800148 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
149 flimflam::kEAPEAPProperty,
150 PropertyStoreTest::kStringV,
151 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700152 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700153 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700154 {
155 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800156 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
157 flimflam::kFavoriteProperty,
158 PropertyStoreTest::kBoolV,
159 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700160 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700161 }
Thieu Le284fe792012-01-31 17:53:19 -0800162 {
163 ::DBus::Error error;
164 service_->set_favorite(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800165 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
166 flimflam::kAutoConnectProperty,
167 PropertyStoreTest::kBoolV,
168 &error));
Thieu Le284fe792012-01-31 17:53:19 -0800169 }
170 {
171 ::DBus::Error error;
172 service_->set_favorite(false);
Wade Guthrie4f28e8b2012-04-11 10:52:07 -0700173 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800174 flimflam::kAutoConnectProperty,
175 PropertyStoreTest::kBoolV,
176 &error));
Thieu Le284fe792012-01-31 17:53:19 -0800177 }
Paul Stewart0c438332012-04-11 07:55:27 -0700178 // Ensure that we can perform a trivial set of the Name property (to its
179 // current value) but an attempt to set the property to a different value
180 // fails.
181 {
182 ::DBus::Error error;
183 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
184 flimflam::kNameProperty,
185 DBusAdaptor::StringToVariant(
186 service_->friendly_name()),
187 &error));
188 }
189 {
190 ::DBus::Error error;
191 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
192 flimflam::kNameProperty,
193 PropertyStoreTest::kStringV,
194 &error));
195 EXPECT_EQ(invalid_args(), error.name());
196 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700197}
198
Darin Petkovba40dd32011-07-11 20:06:39 -0700199TEST_F(ServiceTest, Load) {
200 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700201 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
202 EXPECT_CALL(storage, GetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700203 .Times(AtLeast(1))
204 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700205 EXPECT_TRUE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700206}
207
208TEST_F(ServiceTest, LoadFail) {
209 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700210 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700211 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700212}
213
214TEST_F(ServiceTest, SaveString) {
215 MockStore storage;
216 static const char kKey[] = "test-key";
217 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700218 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700219 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700220 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700221}
222
223TEST_F(ServiceTest, SaveStringCrypted) {
224 MockStore storage;
225 static const char kKey[] = "test-key";
226 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700227 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700228 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700229 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700230}
231
232TEST_F(ServiceTest, SaveStringDontSave) {
233 MockStore storage;
234 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700235 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700236 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700237 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700238}
239
240TEST_F(ServiceTest, SaveStringEmpty) {
241 MockStore storage;
242 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700243 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700244 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700245 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700246}
247
248TEST_F(ServiceTest, Save) {
249 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700250 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700251 .Times(AtLeast(1))
252 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700253 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700254 .Times(AtLeast(1))
255 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700256 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700257}
258
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800259TEST_F(ServiceTest, Unload) {
260 NiceMock<MockStore> storage;
261 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
262 static const string string_value("value");
263 EXPECT_CALL(storage, GetString(storage_id_, _, _))
264 .Times(AtLeast(1))
265 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
266 ASSERT_TRUE(service_->Load(&storage));
267 // TODO(pstew): A single string property in the service is tested as
268 // a sentinel that properties are being set and reset at the rit times.
269 // However, since property load/store is essentially a manual process,
270 // it is error prone and should either be exhaustively unit-tested or
271 // a generic framework for registering loaded/stored properties should
272 // be created. crosbug.com/24859
273 EXPECT_EQ(string_value, service_->ui_data_);
274 service_->Unload();
275 EXPECT_EQ(string(""), service_->ui_data_);
276}
277
Paul Stewart03dba0b2011-08-22 16:32:45 -0700278TEST_F(ServiceTest, State) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400279 EXPECT_EQ(Service::kStateIdle, service_->state());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700280 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
281
mukesh agrawal00917ce2011-11-22 23:56:55 +0000282 ServiceRefPtr service_ref(service_);
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700283
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400284 EXPECT_CALL(*dynamic_cast<ServiceMockAdaptor *>(service_->adaptor_.get()),
285 EmitStringChanged(flimflam::kStateProperty, _)).Times(5);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700286 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
287 service_->SetState(Service::kStateConnected);
288 // A second state change shouldn't cause another update
289 service_->SetState(Service::kStateConnected);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700290 EXPECT_EQ(Service::kStateConnected, service_->state());
291 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
mukesh agrawal568b5c62012-02-28 14:44:47 -0800292
Paul Stewart03dba0b2011-08-22 16:32:45 -0700293 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
294 service_->SetState(Service::kStateDisconnected);
295
296 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
297 service_->SetFailure(Service::kFailureOutOfRange);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800298 EXPECT_TRUE(service_->IsFailed());
299 EXPECT_GT(service_->failed_time_, 0);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700300 EXPECT_EQ(Service::kStateFailure, service_->state());
301 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
mukesh agrawal568b5c62012-02-28 14:44:47 -0800302
303 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
304 service_->SetState(Service::kStateConnected);
305 EXPECT_FALSE(service_->IsFailed());
306 EXPECT_EQ(service_->failed_time_, 0);
307
308 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
309 service_->SetFailureSilent(Service::kFailurePinMissing);
310 EXPECT_TRUE(service_->IsFailed());
311 EXPECT_GT(service_->failed_time_, 0);
312 EXPECT_EQ(Service::kStateIdle, service_->state());
313 EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700314}
315
Darin Petkovb100ae72011-08-24 16:19:45 -0700316TEST_F(ServiceTest, ActivateCellularModem) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500317 ResultCallback callback =
318 Bind(&ServiceTest::TestCallback, Unretained(this));
319 EXPECT_CALL(*this, TestCallback(_)).Times(0);
Darin Petkovb100ae72011-08-24 16:19:45 -0700320 Error error;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500321 service_->ActivateCellularModem("Carrier", &error, callback);
322 EXPECT_TRUE(error.IsFailure());
Darin Petkovb100ae72011-08-24 16:19:45 -0700323}
324
mukesh agrawal00917ce2011-11-22 23:56:55 +0000325TEST_F(ServiceTest, MakeFavorite) {
326 EXPECT_FALSE(service_->favorite());
327 EXPECT_FALSE(service_->auto_connect());
328
329 service_->MakeFavorite();
330 EXPECT_TRUE(service_->favorite());
331 EXPECT_TRUE(service_->auto_connect());
332}
333
334TEST_F(ServiceTest, ReMakeFavorite) {
335 service_->MakeFavorite();
336 EXPECT_TRUE(service_->favorite());
337 EXPECT_TRUE(service_->auto_connect());
338
339 service_->set_auto_connect(false);
340 service_->MakeFavorite();
341 EXPECT_TRUE(service_->favorite());
342 EXPECT_FALSE(service_->auto_connect());
343}
344
mukesh agrawal76d13882012-01-12 15:23:11 -0800345TEST_F(ServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800346 const char *reason;
mukesh agrawal76d13882012-01-12 15:23:11 -0800347 service_->set_connectable(true);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800348 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawal76d13882012-01-12 15:23:11 -0800349
mukesh agrawaladb68482012-01-17 16:31:51 -0800350 // We should not auto-connect to a Service that a user has
351 // deliberately disconnected.
352 Error error;
353 service_->Disconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800354 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
355 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
mukesh agrawaladb68482012-01-17 16:31:51 -0800356
357 // But if the Service is reloaded, it is eligible for auto-connect
358 // again.
359 NiceMock<MockStore> storage;
360 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
361 EXPECT_TRUE(service_->Load(&storage));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800362 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800363
364 // A deliberate Connect should also re-enable auto-connect.
365 service_->Disconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800366 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800367 service_->Connect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800368 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800369
370 // TODO(quiche): After we have resume handling in place, test that
371 // we re-enable auto-connect on resume. crosbug.com/25213
372
mukesh agrawal76d13882012-01-12 15:23:11 -0800373 service_->SetState(Service::kStateConnected);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800374 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
375 EXPECT_STREQ(Service::kAutoConnConnected, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -0800376
377 service_->SetState(Service::kStateAssociating);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800378 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
379 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -0800380}
381
Paul Stewartcb59fed2012-03-21 21:14:46 -0700382TEST_F(ServiceTest, ConfigureBadProperty) {
383 KeyValueStore args;
384 args.SetString("XXXInvalid", "Value");
385 Error error;
386 service_->Configure(args, &error);
387 EXPECT_FALSE(error.IsSuccess());
388}
389
390TEST_F(ServiceTest, ConfigureBoolProperty) {
391 service_->MakeFavorite();
392 service_->set_auto_connect(false);
393 ASSERT_FALSE(service_->auto_connect());
394 KeyValueStore args;
395 args.SetBool(flimflam::kAutoConnectProperty, true);
396 Error error;
397 service_->Configure(args, &error);
398 EXPECT_TRUE(error.IsSuccess());
399 EXPECT_TRUE(service_->auto_connect());
400}
401
402TEST_F(ServiceTest, ConfigureStringProperty) {
403 const string kEAPManagement0 = "management_zero";
404 const string kEAPManagement1 = "management_one";
405 service_->SetEAPKeyManagement(kEAPManagement0);
406 ASSERT_EQ(kEAPManagement0, service_->GetEAPKeyManagement());
407 KeyValueStore args;
408 args.SetString(flimflam::kEapKeyMgmtProperty, kEAPManagement1);
409 Error error;
410 service_->Configure(args, &error);
411 EXPECT_TRUE(error.IsSuccess());
412 EXPECT_EQ(kEAPManagement1, service_->GetEAPKeyManagement());
413}
414
415TEST_F(ServiceTest, ConfigureIgnoredProperty) {
416 service_->MakeFavorite();
417 service_->set_auto_connect(false);
418 ASSERT_FALSE(service_->auto_connect());
419 KeyValueStore args;
420 args.SetBool(flimflam::kAutoConnectProperty, true);
421 Error error;
422 service_->IgnoreParameterForConfigure(flimflam::kAutoConnectProperty);
423 service_->Configure(args, &error);
424 EXPECT_TRUE(error.IsSuccess());
425 EXPECT_FALSE(service_->auto_connect());
426}
427
Paul Stewart10ccbb32012-04-26 15:59:30 -0700428TEST_F(ServiceTest, IsRemembered) {
429 ServiceConstRefPtr service_ref(service_);
430 service_->set_profile(NULL);
431 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
432 EXPECT_FALSE(service_->IsRemembered());
433
434 scoped_refptr<MockProfile> profile(
435 new StrictMock<MockProfile>(control_interface(), manager()));
436 service_->set_profile(profile);
437 EXPECT_CALL(mock_manager_, IsServiceEphemeral(service_ref))
438 .WillOnce(Return(true))
439 .WillOnce(Return(false));
440 EXPECT_FALSE(service_->IsRemembered());
441 EXPECT_TRUE(service_->IsRemembered());
442}
443
Paul Stewartff14b022012-04-24 20:06:23 -0700444TEST_F(ServiceTest, OnPropertyChanged) {
445 scoped_refptr<MockProfile> profile(
446 new StrictMock<MockProfile>(control_interface(), manager()));
447 service_->set_profile(NULL);
448 // Expect no crash.
449 service_->OnPropertyChanged("");
450
451 // Expect no call to Update if the profile has no storage.
452 service_->set_profile(profile);
453 EXPECT_CALL(*profile, UpdateService(_)).Times(0);
454 EXPECT_CALL(*profile, GetConstStorage())
455 .WillOnce(Return(reinterpret_cast<StoreInterface *>(NULL)));
456 service_->OnPropertyChanged("");
457
458 // Expect call to Update if the profile has storage.
459 EXPECT_CALL(*profile, UpdateService(_)).Times(1);
460 NiceMock<MockStore> storage;
461 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
462 service_->OnPropertyChanged("");
463}
464
Paul Stewartd215af62012-04-24 23:25:50 -0700465
466TEST_F(ServiceTest, RecheckPortal) {
467 ServiceRefPtr service_ref(service_);
468 service_->state_ = Service::kStateIdle;
469 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
470 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
471
472 service_->state_ = Service::kStatePortal;
473 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
474 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
475
476 service_->state_ = Service::kStateConnected;
477 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
478 service_->OnPropertyChanged(flimflam::kProxyConfigProperty);
479
480 service_->state_ = Service::kStateOnline;
481 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
482 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
483
484 service_->state_ = Service::kStatePortal;
485 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
486 service_->OnPropertyChanged(flimflam::kEAPKeyIDProperty);
487}
488
489TEST_F(ServiceTest, SetCheckPortal) {
490 ServiceRefPtr service_ref(service_);
491 {
492 Error error;
493 service_->SetCheckPortal("false", &error);
494 EXPECT_TRUE(error.IsSuccess());
495 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
496 }
497 {
498 Error error;
499 service_->SetCheckPortal("true", &error);
500 EXPECT_TRUE(error.IsSuccess());
501 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
502 }
503 {
504 Error error;
505 service_->SetCheckPortal("auto", &error);
506 EXPECT_TRUE(error.IsSuccess());
507 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
508 }
509 {
510 Error error;
511 service_->SetCheckPortal("xxx", &error);
512 EXPECT_FALSE(error.IsSuccess());
513 EXPECT_EQ(Error::kInvalidArguments, error.type());
514 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
515 }
516}
517
Paul Stewart9f32d192012-01-30 20:37:50 -0800518// Make sure a property is registered as a write only property
519// by reading and comparing all string properties returned on the store.
520// Subtle: We need to convert the test argument back and forth between
521// string and ::DBus::Variant because this is the parameter type that
522// our supeclass (PropertyStoreTest) is declared with.
523class ReadOnlyServicePropertyTest : public ServiceTest {};
524TEST_P(ReadOnlyServicePropertyTest, PropertyWriteOnly) {
Paul Stewart9f32d192012-01-30 20:37:50 -0800525 string property(GetParam().reader().get_string());
Paul Stewart8e7e4592012-04-29 09:47:48 -0700526 PropertyStoreInspector inspector(&service_->store());
527 EXPECT_FALSE(inspector.ContainsStringProperty(property));
Paul Stewart9f32d192012-01-30 20:37:50 -0800528}
529
530INSTANTIATE_TEST_CASE_P(
531 ReadOnlyServicePropertyTestInstance,
532 ReadOnlyServicePropertyTest,
533 Values(
534 DBusAdaptor::StringToVariant(flimflam::kEapPrivateKeyPasswordProperty),
535 DBusAdaptor::StringToVariant(flimflam::kEapPasswordProperty)));
536
Paul Stewart10241e32012-04-23 18:15:06 -0700537
538TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
539 {
540 Error error;
541 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
542 EXPECT_EQ(Error::kNotFound, error.type());
543 }
544
545 scoped_ptr<MockDeviceInfo> mock_device_info(
546 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
547 &mock_manager_));
548 scoped_refptr<MockConnection> mock_connection(
549 new NiceMock<MockConnection>(mock_device_info.get()));
550
551 service_->connection_ = mock_connection;
552
553 {
554 Error error;
555 const string empty_string;
556 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
557 .WillOnce(ReturnRef(empty_string));
558 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
559 EXPECT_EQ(Error::kNotFound, error.type());
560 }
561
562 {
563 Error error;
564 const string nonempty_string("/ipconfig/path");
565 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
566 .WillOnce(ReturnRef(nonempty_string));
567 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
568 EXPECT_EQ(Error::kSuccess, error.type());
569 }
570
571 // Assure orderly destruction of the Connection before DeviceInfo.
572 service_->connection_ = NULL;
573 mock_connection = NULL;
574 mock_device_info.reset();
575}
576
Paul Stewart81426132012-05-16 10:05:10 -0700577class ServiceWithMockSetEap : public ServiceUnderTest {
578 public:
579 ServiceWithMockSetEap(ControlInterface *control_interface,
580 EventDispatcher *dispatcher,
581 Metrics *metrics,
582 Manager *manager)
583 : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
584 is_8021x_(false) {}
585 MOCK_METHOD1(set_eap, void(const EapCredentials &eap));
586 virtual bool Is8021x() const { return is_8021x_; }
587 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }
588
589 private:
590 bool is_8021x_;
591};
592
593TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
594 scoped_refptr<ServiceWithMockSetEap> service(
595 new ServiceWithMockSetEap(control_interface(),
596 dispatcher(),
597 metrics(),
598 &mock_manager_));
599 string eap_credential_properties[] = {
600 flimflam::kEAPCertIDProperty,
601 flimflam::kEAPClientCertProperty,
602 flimflam::kEAPKeyIDProperty,
603 flimflam::kEAPPINProperty,
604 flimflam::kEapCaCertIDProperty,
605 flimflam::kEapIdentityProperty,
606 flimflam::kEapPasswordProperty,
607 flimflam::kEapPrivateKeyProperty
608 };
609 string eap_non_credential_properties[] = {
610 flimflam::kEAPEAPProperty,
611 flimflam::kEapPhase2AuthProperty,
612 flimflam::kEapAnonymousIdentityProperty,
613 flimflam::kEapPrivateKeyPasswordProperty,
614 flimflam::kEapKeyMgmtProperty,
615 flimflam::kEapCaCertNssProperty,
616 flimflam::kEapUseSystemCAsProperty
617 };
618 // While this is not an 802.1x-based service, none of these property
619 // changes should cause a call to set_eap().
620 EXPECT_CALL(*service, set_eap(_)).Times(0);
621 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
622 service->OnPropertyChanged(eap_credential_properties[i]);
623 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
624 service->OnPropertyChanged(eap_non_credential_properties[i]);
625
626 service->set_is_8021x(true);
627
628 // When this is an 802.1x-based service, set_eap should be called for
629 // all credential-carrying properties.
630 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
631 EXPECT_CALL(*service, set_eap(_)).Times(1);
632 service->OnPropertyChanged(eap_credential_properties[i]);
633 Mock::VerifyAndClearExpectations(service.get());
634 }
635 EXPECT_CALL(*service, set_eap(_)).Times(0);
636 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
637 service->OnPropertyChanged(eap_non_credential_properties[i]);
638}
639
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700640} // namespace shill