blob: 8f2daab96cd05f206f360d0b6787d17551add652 [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
Chris Masone3bd3c8c2011-06-13 08:20:26 -070011#include <chromeos/dbus/service_constants.h>
mukesh agrawal1830fa12011-09-26 14:31:40 -070012#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013#include <gtest/gtest.h>
14#include <gmock/gmock.h>
15
16#include "shill/dbus_adaptor.h"
17#include "shill/ethernet_service.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070018#include "shill/event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070019#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070020#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070021#include "shill/mock_control.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070022#include "shill/mock_manager.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070023#include "shill/mock_store.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070024#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070025#include "shill/service_under_test.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070026
27using std::map;
28using std::string;
29using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070030using testing::_;
31using testing::AtLeast;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080032using testing::DoAll;
Darin Petkovba40dd32011-07-11 20:06:39 -070033using testing::NiceMock;
34using testing::Return;
35using testing::StrictMock;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080036using testing::SetArgumentPointee;
Darin Petkovba40dd32011-07-11 20:06:39 -070037using testing::Test;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070038
39namespace shill {
40
41class ServiceTest : public PropertyStoreTest {
42 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070043 ServiceTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080044 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
Chris Masone2176a882011-09-14 22:29:15 -070045 service_(new ServiceUnderTest(control_interface(),
46 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080047 metrics(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070048 &mock_manager_)),
Chris Masone9d779932011-08-25 16:33:41 -070049 storage_id_(ServiceUnderTest::kStorageId) {
50 }
Chris Masoneb925cc82011-06-22 15:39:57 -070051
Chris Masone3bd3c8c2011-06-13 08:20:26 -070052 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -070053
54 protected:
Paul Stewart03dba0b2011-08-22 16:32:45 -070055 MockManager mock_manager_;
56 scoped_refptr<ServiceUnderTest> service_;
Chris Masone34af2182011-08-22 11:59:36 -070057 string storage_id_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070058};
59
Darin Petkovba40dd32011-07-11 20:06:39 -070060TEST_F(ServiceTest, Constructor) {
61 EXPECT_TRUE(service_->save_credentials_);
62 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
63}
64
Chris Masonea8a2c252011-06-27 22:16:30 -070065TEST_F(ServiceTest, GetProperties) {
66 map<string, ::DBus::Variant> props;
67 Error error(Error::kInvalidProperty, "");
68 {
69 ::DBus::Error dbus_error;
70 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -070071 service_->mutable_store()->SetStringProperty(flimflam::kCheckPortalProperty,
72 expected,
73 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070074 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070075 ASSERT_FALSE(props.find(flimflam::kCheckPortalProperty) == props.end());
76 EXPECT_EQ(props[flimflam::kCheckPortalProperty].reader().get_string(),
77 expected);
78 }
79 {
80 ::DBus::Error dbus_error;
81 bool expected = true;
Thieu Le284fe792012-01-31 17:53:19 -080082 service_->set_favorite(true);
mukesh agrawalde29fa82011-09-16 16:16:36 -070083 service_->mutable_store()->SetBoolProperty(flimflam::kAutoConnectProperty,
84 expected,
85 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070086 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070087 ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
88 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
89 expected);
90 }
91 {
92 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -070093 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070094 ASSERT_FALSE(props.find(flimflam::kConnectableProperty) == props.end());
95 EXPECT_EQ(props[flimflam::kConnectableProperty].reader().get_bool(), false);
96 }
97 {
98 ::DBus::Error dbus_error;
99 int32 expected = 127;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700100 service_->mutable_store()->SetInt32Property(flimflam::kPriorityProperty,
101 expected,
102 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700103 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700104 ASSERT_FALSE(props.find(flimflam::kPriorityProperty) == props.end());
105 EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
106 expected);
107 }
Chris Masone95207da2011-06-29 16:50:49 -0700108 {
109 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700110 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masone95207da2011-06-29 16:50:49 -0700111 ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
112 EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_string(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700113 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700114 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700115}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700116
Chris Masonea8a2c252011-06-27 22:16:30 -0700117TEST_F(ServiceTest, Dispatch) {
118 {
119 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700120 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700121 flimflam::kSaveCredentialsProperty,
122 PropertyStoreTest::kBoolV,
123 &error));
124 }
125 {
126 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700127 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700128 flimflam::kPriorityProperty,
129 PropertyStoreTest::kInt32V,
130 &error));
131 }
132 {
133 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700134 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700135 flimflam::kEAPEAPProperty,
136 PropertyStoreTest::kStringV,
137 &error));
138 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700139 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700140 {
141 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700142 EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700143 flimflam::kFavoriteProperty,
144 PropertyStoreTest::kBoolV,
145 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700146 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700147 }
Thieu Le284fe792012-01-31 17:53:19 -0800148 {
149 ::DBus::Error error;
150 service_->set_favorite(true);
151 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
152 flimflam::kAutoConnectProperty,
153 PropertyStoreTest::kBoolV,
154 &error));
155 }
156 {
157 ::DBus::Error error;
158 service_->set_favorite(false);
159 EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
160 flimflam::kAutoConnectProperty,
161 PropertyStoreTest::kBoolV,
162 &error));
163 EXPECT_EQ(invalid_args(), error.name());
164 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700165}
166
Darin Petkovba40dd32011-07-11 20:06:39 -0700167TEST_F(ServiceTest, Load) {
168 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700169 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
170 EXPECT_CALL(storage, GetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700171 .Times(AtLeast(1))
172 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700173 EXPECT_TRUE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700174}
175
176TEST_F(ServiceTest, LoadFail) {
177 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700178 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700179 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700180}
181
182TEST_F(ServiceTest, SaveString) {
183 MockStore storage;
184 static const char kKey[] = "test-key";
185 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700186 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700187 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700188 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700189}
190
191TEST_F(ServiceTest, SaveStringCrypted) {
192 MockStore storage;
193 static const char kKey[] = "test-key";
194 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700195 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700196 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700197 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700198}
199
200TEST_F(ServiceTest, SaveStringDontSave) {
201 MockStore storage;
202 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700203 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700204 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700205 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700206}
207
208TEST_F(ServiceTest, SaveStringEmpty) {
209 MockStore storage;
210 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700211 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700212 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700213 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700214}
215
216TEST_F(ServiceTest, Save) {
217 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700218 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700219 .Times(AtLeast(1))
220 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700221 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700222 .Times(AtLeast(1))
223 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700224 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700225}
226
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800227TEST_F(ServiceTest, Unload) {
228 NiceMock<MockStore> storage;
229 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
230 static const string string_value("value");
231 EXPECT_CALL(storage, GetString(storage_id_, _, _))
232 .Times(AtLeast(1))
233 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
234 ASSERT_TRUE(service_->Load(&storage));
235 // TODO(pstew): A single string property in the service is tested as
236 // a sentinel that properties are being set and reset at the rit times.
237 // However, since property load/store is essentially a manual process,
238 // it is error prone and should either be exhaustively unit-tested or
239 // a generic framework for registering loaded/stored properties should
240 // be created. crosbug.com/24859
241 EXPECT_EQ(string_value, service_->ui_data_);
242 service_->Unload();
243 EXPECT_EQ(string(""), service_->ui_data_);
244}
245
Paul Stewart03dba0b2011-08-22 16:32:45 -0700246TEST_F(ServiceTest, State) {
247 EXPECT_EQ(Service::kStateUnknown, service_->state());
248 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
249
mukesh agrawal00917ce2011-11-22 23:56:55 +0000250 ServiceRefPtr service_ref(service_);
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700251
252 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
253 // EXPECT_CALL(*dynamic_cast<ServiceMockAdaptor *>(service_->adaptor_.get()),
254 // EmitStringChanged(flimflam::kStateProperty, _));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700255 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
256 service_->SetState(Service::kStateConnected);
257 // A second state change shouldn't cause another update
258 service_->SetState(Service::kStateConnected);
259
260 EXPECT_EQ(Service::kStateConnected, service_->state());
261 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
262 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
263 service_->SetState(Service::kStateDisconnected);
264
265 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
266 service_->SetFailure(Service::kFailureOutOfRange);
267
268 EXPECT_EQ(Service::kStateFailure, service_->state());
269 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
270}
271
Darin Petkovb100ae72011-08-24 16:19:45 -0700272TEST_F(ServiceTest, ActivateCellularModem) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500273 MockReturner returner;
274 EXPECT_CALL(returner, Return()).Times(0);
275 EXPECT_CALL(returner, ReturnError(_));
Darin Petkovb100ae72011-08-24 16:19:45 -0700276 Error error;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500277 service_->ActivateCellularModem("Carrier", &returner);
Darin Petkovb100ae72011-08-24 16:19:45 -0700278}
279
mukesh agrawal00917ce2011-11-22 23:56:55 +0000280TEST_F(ServiceTest, MakeFavorite) {
281 EXPECT_FALSE(service_->favorite());
282 EXPECT_FALSE(service_->auto_connect());
283
284 service_->MakeFavorite();
285 EXPECT_TRUE(service_->favorite());
286 EXPECT_TRUE(service_->auto_connect());
287}
288
289TEST_F(ServiceTest, ReMakeFavorite) {
290 service_->MakeFavorite();
291 EXPECT_TRUE(service_->favorite());
292 EXPECT_TRUE(service_->auto_connect());
293
294 service_->set_auto_connect(false);
295 service_->MakeFavorite();
296 EXPECT_TRUE(service_->favorite());
297 EXPECT_FALSE(service_->auto_connect());
298}
299
mukesh agrawal76d13882012-01-12 15:23:11 -0800300TEST_F(ServiceTest, IsAutoConnectable) {
301 service_->set_connectable(true);
302 EXPECT_TRUE(service_->IsAutoConnectable());
303
mukesh agrawaladb68482012-01-17 16:31:51 -0800304 // We should not auto-connect to a Service that a user has
305 // deliberately disconnected.
306 Error error;
307 service_->Disconnect(&error);
308 EXPECT_FALSE(service_->IsAutoConnectable());
309
310 // But if the Service is reloaded, it is eligible for auto-connect
311 // again.
312 NiceMock<MockStore> storage;
313 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
314 EXPECT_TRUE(service_->Load(&storage));
315 EXPECT_TRUE(service_->IsAutoConnectable());
316
317 // A deliberate Connect should also re-enable auto-connect.
318 service_->Disconnect(&error);
319 EXPECT_FALSE(service_->IsAutoConnectable());
320 service_->Connect(&error);
321 EXPECT_TRUE(service_->IsAutoConnectable());
322
323 // TODO(quiche): After we have resume handling in place, test that
324 // we re-enable auto-connect on resume. crosbug.com/25213
325
mukesh agrawal76d13882012-01-12 15:23:11 -0800326 service_->SetState(Service::kStateConnected);
327 EXPECT_FALSE(service_->IsAutoConnectable());
328
329 service_->SetState(Service::kStateAssociating);
330 EXPECT_FALSE(service_->IsAutoConnectable());
331}
332
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700333} // namespace shill