blob: c65703b8ae43b5009abafbab0087be7ae39dcca8 [file] [log] [blame]
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001// Copyright (c) 2011 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/service.h"
6
7#include <map>
8#include <string>
9#include <vector>
10
11#include <dbus-c++/dbus.h>
12#include <chromeos/dbus/service_constants.h>
13#include <gtest/gtest.h>
14#include <gmock/gmock.h>
15
16#include "shill/dbus_adaptor.h"
17#include "shill/ethernet_service.h"
18#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070019#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070020#include "shill/mock_control.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070021#include "shill/mock_manager.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070022#include "shill/mock_store.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070023#include "shill/property_store_unittest.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070024#include "shill/service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070025#include "shill/shill_event.h"
26
27using std::map;
28using std::string;
29using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070030using testing::_;
31using testing::AtLeast;
32using testing::NiceMock;
33using testing::Return;
34using testing::StrictMock;
35using testing::Test;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036
37namespace shill {
38
Paul Stewart03dba0b2011-08-22 16:32:45 -070039// This is a simple Service subclass with all the pure-virutal methods stubbed
40class ServiceUnderTest : public Service {
41 public:
42 static const char kRpcId[];
43 static const char kStorageId[];
44
45 ServiceUnderTest(ControlInterface *control_interface,
46 EventDispatcher *dispatcher,
47 Manager *manager)
48 : Service(control_interface, dispatcher, manager) {}
49 virtual ~ServiceUnderTest() {}
50
51 virtual void Connect(Error *error) {}
52 virtual void Disconnect() {}
53 virtual string CalculateState() { return ""; }
54 virtual string GetRpcIdentifier() const { return ServiceMockAdaptor::kRpcId; }
55 virtual string GetDeviceRpcId() { return kRpcId; }
Chris Masone9d779932011-08-25 16:33:41 -070056 virtual string GetStorageIdentifier() { return kStorageId; }
Paul Stewart03dba0b2011-08-22 16:32:45 -070057
58 private:
59 DISALLOW_COPY_AND_ASSIGN(ServiceUnderTest);
60};
61
62const char ServiceUnderTest::kRpcId[] = "mock-device-rpc";
63const char ServiceUnderTest::kStorageId[] = "service";
64
Chris Masone3bd3c8c2011-06-13 08:20:26 -070065class ServiceTest : public PropertyStoreTest {
66 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070067 ServiceTest()
Chris Masone2176a882011-09-14 22:29:15 -070068 : mock_manager_(control_interface(), dispatcher(), glib()),
69 service_(new ServiceUnderTest(control_interface(),
70 dispatcher(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070071 &mock_manager_)),
Chris Masone9d779932011-08-25 16:33:41 -070072 storage_id_(ServiceUnderTest::kStorageId) {
73 }
Chris Masoneb925cc82011-06-22 15:39:57 -070074
Chris Masone3bd3c8c2011-06-13 08:20:26 -070075 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -070076
77 protected:
Paul Stewart03dba0b2011-08-22 16:32:45 -070078 MockManager mock_manager_;
79 scoped_refptr<ServiceUnderTest> service_;
Chris Masone34af2182011-08-22 11:59:36 -070080 string storage_id_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070081};
82
Darin Petkovba40dd32011-07-11 20:06:39 -070083TEST_F(ServiceTest, Constructor) {
84 EXPECT_TRUE(service_->save_credentials_);
85 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
86}
87
Chris Masonea8a2c252011-06-27 22:16:30 -070088TEST_F(ServiceTest, GetProperties) {
89 map<string, ::DBus::Variant> props;
90 Error error(Error::kInvalidProperty, "");
91 {
92 ::DBus::Error dbus_error;
93 string expected("portal_list");
Chris Masone27c4aa52011-07-02 13:10:14 -070094 service_->store()->SetStringProperty(flimflam::kCheckPortalProperty,
95 expected,
96 &error);
97 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070098 ASSERT_FALSE(props.find(flimflam::kCheckPortalProperty) == props.end());
99 EXPECT_EQ(props[flimflam::kCheckPortalProperty].reader().get_string(),
100 expected);
101 }
102 {
103 ::DBus::Error dbus_error;
104 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -0700105 service_->store()->SetBoolProperty(flimflam::kAutoConnectProperty,
106 expected,
107 &error);
108 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700109 ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
110 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
111 expected);
112 }
113 {
114 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700115 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700116 ASSERT_FALSE(props.find(flimflam::kConnectableProperty) == props.end());
117 EXPECT_EQ(props[flimflam::kConnectableProperty].reader().get_bool(), false);
118 }
119 {
120 ::DBus::Error dbus_error;
121 int32 expected = 127;
Chris Masone27c4aa52011-07-02 13:10:14 -0700122 service_->store()->SetInt32Property(flimflam::kPriorityProperty,
123 expected,
124 &error);
125 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700126 ASSERT_FALSE(props.find(flimflam::kPriorityProperty) == props.end());
127 EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
128 expected);
129 }
Chris Masone95207da2011-06-29 16:50:49 -0700130 {
131 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700132 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masone95207da2011-06-29 16:50:49 -0700133 ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
134 EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_string(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700135 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700136 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700137}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700138
Chris Masonea8a2c252011-06-27 22:16:30 -0700139TEST_F(ServiceTest, Dispatch) {
140 {
141 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700142 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700143 flimflam::kSaveCredentialsProperty,
144 PropertyStoreTest::kBoolV,
145 &error));
146 }
147 {
148 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700149 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700150 flimflam::kPriorityProperty,
151 PropertyStoreTest::kInt32V,
152 &error));
153 }
154 {
155 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700156 EXPECT_TRUE(DBusAdaptor::DispatchOnType(service_->store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700157 flimflam::kEAPEAPProperty,
158 PropertyStoreTest::kStringV,
159 &error));
160 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700161 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700162 {
163 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700164 EXPECT_FALSE(DBusAdaptor::DispatchOnType(service_->store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700165 flimflam::kFavoriteProperty,
166 PropertyStoreTest::kBoolV,
167 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700168 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700169 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700170}
171
Darin Petkovba40dd32011-07-11 20:06:39 -0700172TEST_F(ServiceTest, Load) {
173 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700174 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
175 EXPECT_CALL(storage, GetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700176 .Times(AtLeast(1))
177 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700178 EXPECT_TRUE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700179}
180
181TEST_F(ServiceTest, LoadFail) {
182 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700183 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700184 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700185}
186
187TEST_F(ServiceTest, SaveString) {
188 MockStore storage;
189 static const char kKey[] = "test-key";
190 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700191 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700192 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700193 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700194}
195
196TEST_F(ServiceTest, SaveStringCrypted) {
197 MockStore storage;
198 static const char kKey[] = "test-key";
199 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700200 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700201 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700202 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700203}
204
205TEST_F(ServiceTest, SaveStringDontSave) {
206 MockStore storage;
207 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700208 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700209 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700210 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700211}
212
213TEST_F(ServiceTest, SaveStringEmpty) {
214 MockStore storage;
215 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700216 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700217 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700218 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700219}
220
221TEST_F(ServiceTest, Save) {
222 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700223 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700224 .Times(AtLeast(1))
225 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700226 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700227 .Times(AtLeast(1))
228 .WillRepeatedly(Return(true));
Chris Masone9d779932011-08-25 16:33:41 -0700229 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700230}
231
Paul Stewart03dba0b2011-08-22 16:32:45 -0700232TEST_F(ServiceTest, State) {
233 EXPECT_EQ(Service::kStateUnknown, service_->state());
234 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
235
236 ServiceConstRefPtr service_ref(service_);
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700237
238 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
239 // EXPECT_CALL(*dynamic_cast<ServiceMockAdaptor *>(service_->adaptor_.get()),
240 // EmitStringChanged(flimflam::kStateProperty, _));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700241 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
242 service_->SetState(Service::kStateConnected);
243 // A second state change shouldn't cause another update
244 service_->SetState(Service::kStateConnected);
245
246 EXPECT_EQ(Service::kStateConnected, service_->state());
247 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
248 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
249 service_->SetState(Service::kStateDisconnected);
250
251 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
252 service_->SetFailure(Service::kFailureOutOfRange);
253
254 EXPECT_EQ(Service::kStateFailure, service_->state());
255 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
256}
257
Darin Petkovb100ae72011-08-24 16:19:45 -0700258TEST_F(ServiceTest, ActivateCellularModem) {
259 Error error;
260 service_->ActivateCellularModem("Carrier", &error);
261 EXPECT_EQ(Error::kInvalidArguments, error.type());
262}
263
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700264} // namespace shill