blob: 634113decfde4f6aa907591149fe36f2a977ee1e [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()
Chris Masone2176a882011-09-14 22:29:15 -070044 : mock_manager_(control_interface(), dispatcher(), glib()),
45 service_(new ServiceUnderTest(control_interface(),
46 dispatcher(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070047 &mock_manager_)),
Chris Masone9d779932011-08-25 16:33:41 -070048 storage_id_(ServiceUnderTest::kStorageId) {
49 }
Chris Masoneb925cc82011-06-22 15:39:57 -070050
Chris Masone3bd3c8c2011-06-13 08:20:26 -070051 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -070052
53 protected:
Paul Stewart03dba0b2011-08-22 16:32:45 -070054 MockManager mock_manager_;
55 scoped_refptr<ServiceUnderTest> service_;
Chris Masone34af2182011-08-22 11:59:36 -070056 string storage_id_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057};
58
Darin Petkovba40dd32011-07-11 20:06:39 -070059TEST_F(ServiceTest, Constructor) {
60 EXPECT_TRUE(service_->save_credentials_);
61 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
62}
63
Chris Masonea8a2c252011-06-27 22:16:30 -070064TEST_F(ServiceTest, GetProperties) {
65 map<string, ::DBus::Variant> props;
66 Error error(Error::kInvalidProperty, "");
67 {
68 ::DBus::Error dbus_error;
69 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -070070 service_->mutable_store()->SetStringProperty(flimflam::kCheckPortalProperty,
71 expected,
72 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070073 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070074 ASSERT_FALSE(props.find(flimflam::kCheckPortalProperty) == props.end());
75 EXPECT_EQ(props[flimflam::kCheckPortalProperty].reader().get_string(),
76 expected);
77 }
78 {
79 ::DBus::Error dbus_error;
80 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -070081 service_->mutable_store()->SetBoolProperty(flimflam::kAutoConnectProperty,
82 expected,
83 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070084 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070085 ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
86 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
87 expected);
88 }
89 {
90 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -070091 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070092 ASSERT_FALSE(props.find(flimflam::kConnectableProperty) == props.end());
93 EXPECT_EQ(props[flimflam::kConnectableProperty].reader().get_bool(), false);
94 }
95 {
96 ::DBus::Error dbus_error;
97 int32 expected = 127;
mukesh agrawalde29fa82011-09-16 16:16:36 -070098 service_->mutable_store()->SetInt32Property(flimflam::kPriorityProperty,
99 expected,
100 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700101 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700102 ASSERT_FALSE(props.find(flimflam::kPriorityProperty) == props.end());
103 EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
104 expected);
105 }
Chris Masone95207da2011-06-29 16:50:49 -0700106 {
107 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700108 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masone95207da2011-06-29 16:50:49 -0700109 ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
110 EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_string(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700111 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700112 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700113}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700114
Chris Masonea8a2c252011-06-27 22:16:30 -0700115TEST_F(ServiceTest, Dispatch) {
116 {
117 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700118 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700119 flimflam::kSaveCredentialsProperty,
120 PropertyStoreTest::kBoolV,
121 &error));
122 }
123 {
124 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700125 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700126 flimflam::kPriorityProperty,
127 PropertyStoreTest::kInt32V,
128 &error));
129 }
130 {
131 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700132 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700133 flimflam::kEAPEAPProperty,
134 PropertyStoreTest::kStringV,
135 &error));
136 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700137 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700138 {
139 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700140 EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700141 flimflam::kFavoriteProperty,
142 PropertyStoreTest::kBoolV,
143 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700144 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700145 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700146}
147
Darin Petkovba40dd32011-07-11 20:06:39 -0700148TEST_F(ServiceTest, Load) {
149 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700150 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
151 EXPECT_CALL(storage, GetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700152 .Times(AtLeast(1))
153 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700154 EXPECT_TRUE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700155}
156
157TEST_F(ServiceTest, LoadFail) {
158 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700159 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700160 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700161}
162
163TEST_F(ServiceTest, SaveString) {
164 MockStore storage;
165 static const char kKey[] = "test-key";
166 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700167 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700168 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700169 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700170}
171
172TEST_F(ServiceTest, SaveStringCrypted) {
173 MockStore storage;
174 static const char kKey[] = "test-key";
175 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700176 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700177 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700178 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700179}
180
181TEST_F(ServiceTest, SaveStringDontSave) {
182 MockStore storage;
183 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700184 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700185 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700186 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700187}
188
189TEST_F(ServiceTest, SaveStringEmpty) {
190 MockStore storage;
191 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700192 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700193 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700194 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700195}
196
197TEST_F(ServiceTest, Save) {
198 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700199 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700200 .Times(AtLeast(1))
201 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700202 EXPECT_CALL(storage, DeleteKey(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_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700206}
207
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800208TEST_F(ServiceTest, Unload) {
209 NiceMock<MockStore> storage;
210 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
211 static const string string_value("value");
212 EXPECT_CALL(storage, GetString(storage_id_, _, _))
213 .Times(AtLeast(1))
214 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
215 ASSERT_TRUE(service_->Load(&storage));
216 // TODO(pstew): A single string property in the service is tested as
217 // a sentinel that properties are being set and reset at the rit times.
218 // However, since property load/store is essentially a manual process,
219 // it is error prone and should either be exhaustively unit-tested or
220 // a generic framework for registering loaded/stored properties should
221 // be created. crosbug.com/24859
222 EXPECT_EQ(string_value, service_->ui_data_);
223 service_->Unload();
224 EXPECT_EQ(string(""), service_->ui_data_);
225}
226
Paul Stewart03dba0b2011-08-22 16:32:45 -0700227TEST_F(ServiceTest, State) {
228 EXPECT_EQ(Service::kStateUnknown, service_->state());
229 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
230
mukesh agrawal00917ce2011-11-22 23:56:55 +0000231 ServiceRefPtr service_ref(service_);
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700232
233 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
234 // EXPECT_CALL(*dynamic_cast<ServiceMockAdaptor *>(service_->adaptor_.get()),
235 // EmitStringChanged(flimflam::kStateProperty, _));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700236 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
237 service_->SetState(Service::kStateConnected);
238 // A second state change shouldn't cause another update
239 service_->SetState(Service::kStateConnected);
240
241 EXPECT_EQ(Service::kStateConnected, service_->state());
242 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
243 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
244 service_->SetState(Service::kStateDisconnected);
245
246 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
247 service_->SetFailure(Service::kFailureOutOfRange);
248
249 EXPECT_EQ(Service::kStateFailure, service_->state());
250 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
251}
252
Darin Petkovb100ae72011-08-24 16:19:45 -0700253TEST_F(ServiceTest, ActivateCellularModem) {
254 Error error;
255 service_->ActivateCellularModem("Carrier", &error);
256 EXPECT_EQ(Error::kInvalidArguments, error.type());
257}
258
mukesh agrawal00917ce2011-11-22 23:56:55 +0000259TEST_F(ServiceTest, MakeFavorite) {
260 EXPECT_FALSE(service_->favorite());
261 EXPECT_FALSE(service_->auto_connect());
262
263 service_->MakeFavorite();
264 EXPECT_TRUE(service_->favorite());
265 EXPECT_TRUE(service_->auto_connect());
266}
267
268TEST_F(ServiceTest, ReMakeFavorite) {
269 service_->MakeFavorite();
270 EXPECT_TRUE(service_->favorite());
271 EXPECT_TRUE(service_->auto_connect());
272
273 service_->set_auto_connect(false);
274 service_->MakeFavorite();
275 EXPECT_TRUE(service_->favorite());
276 EXPECT_FALSE(service_->auto_connect());
277}
278
mukesh agrawal76d13882012-01-12 15:23:11 -0800279TEST_F(ServiceTest, IsAutoConnectable) {
280 service_->set_connectable(true);
281 EXPECT_TRUE(service_->IsAutoConnectable());
282
283 service_->SetState(Service::kStateConnected);
284 EXPECT_FALSE(service_->IsAutoConnectable());
285
286 service_->SetState(Service::kStateAssociating);
287 EXPECT_FALSE(service_->IsAutoConnectable());
288}
289
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700290} // namespace shill