blob: 261f0618344c96f229657183fb84b47e862bc154 [file] [log] [blame]
Chris Masone9be4a9d2011-05-16 15:44:09 -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.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07004
5#include "shill/manager.h"
6
Chris Masone6791a432011-07-12 13:23:19 -07007#include <set>
8
Chris Masone9be4a9d2011-05-16 15:44:09 -07009#include <glib.h>
10
Chris Masone9be4a9d2011-05-16 15:44:09 -070011#include <base/logging.h>
Chris Masone6791a432011-07-12 13:23:19 -070012#include <base/stl_util-inl.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070014#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070015#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070016
Chris Masoned7732e42011-05-20 11:08:56 -070017#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070018#include "shill/mock_device.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070019#include "shill/mock_glib.h"
20#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070021#include "shill/mock_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070022#include "shill/property_store_unittest.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070023
24using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070025using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070026using std::string;
27using std::vector;
28
Chris Masone9be4a9d2011-05-16 15:44:09 -070029namespace shill {
30using ::testing::Test;
31using ::testing::_;
32using ::testing::NiceMock;
33using ::testing::Return;
Chris Masone9be4a9d2011-05-16 15:44:09 -070034
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070036 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070037 ManagerTest()
Darin Petkov6f9eaa32011-08-09 15:26:44 -070038 : mock_device_(new NiceMock<MockDevice>(&control_interface_,
Chris Masone3c3f6a12011-07-01 10:01:41 -070039 &dispatcher_,
40 &manager_,
41 "null0",
Chris Masone626719f2011-08-18 16:58:48 -070042 "addr0",
Darin Petkov6f9eaa32011-08-09 15:26:44 -070043 0)),
Chris Masone3c3f6a12011-07-01 10:01:41 -070044 mock_device2_(new NiceMock<MockDevice>(&control_interface_,
45 &dispatcher_,
46 &manager_,
Darin Petkov6f9eaa32011-08-09 15:26:44 -070047 "null2",
Chris Masone626719f2011-08-18 16:58:48 -070048 "addr2",
Darin Petkov6f9eaa32011-08-09 15:26:44 -070049 2)),
50 mock_device3_(new NiceMock<MockDevice>(&control_interface_,
51 &dispatcher_,
52 &manager_,
53 "null3",
Chris Masone626719f2011-08-18 16:58:48 -070054 "addr3",
Darin Petkov6f9eaa32011-08-09 15:26:44 -070055 3)) {
Chris Masone3c3f6a12011-07-01 10:01:41 -070056 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -070058
Chris Masone2b105542011-06-22 10:58:09 -070059 bool IsDeviceRegistered(const DeviceRefPtr &device, Device::Technology tech) {
Chris Masonec1e50412011-06-07 13:04:53 -070060 vector<DeviceRefPtr> devices;
Chris Masone9be4a9d2011-05-16 15:44:09 -070061 manager_.FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -070062 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -070063 }
64
Paul Stewartf1ce5d22011-05-19 13:10:20 -070065 protected:
Chris Masone3c3f6a12011-07-01 10:01:41 -070066 scoped_refptr<MockDevice> mock_device_;
67 scoped_refptr<MockDevice> mock_device2_;
Darin Petkov6f9eaa32011-08-09 15:26:44 -070068 scoped_refptr<MockDevice> mock_device3_;
Chris Masone9be4a9d2011-05-16 15:44:09 -070069};
70
Chris Masone3bd3c8c2011-06-13 08:20:26 -070071TEST_F(ManagerTest, Contains) {
Chris Masone27c4aa52011-07-02 13:10:14 -070072 EXPECT_TRUE(manager_.store()->Contains(flimflam::kStateProperty));
73 EXPECT_FALSE(manager_.store()->Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -070074}
75
Chris Masone9be4a9d2011-05-16 15:44:09 -070076TEST_F(ManagerTest, DeviceRegistration) {
Chris Masone3c3f6a12011-07-01 10:01:41 -070077 ON_CALL(*mock_device_.get(), TechnologyIs(Device::kEthernet))
78 .WillByDefault(Return(true));
79 ON_CALL(*mock_device2_.get(), TechnologyIs(Device::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -070080 .WillByDefault(Return(true));
Darin Petkov6f9eaa32011-08-09 15:26:44 -070081 ON_CALL(*mock_device3_.get(), TechnologyIs(Device::kCellular))
82 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -070083
Darin Petkov6f9eaa32011-08-09 15:26:44 -070084 manager_.RegisterDevice(mock_device_);
85 manager_.RegisterDevice(mock_device2_);
86 manager_.RegisterDevice(mock_device3_);
Chris Masone9be4a9d2011-05-16 15:44:09 -070087
Chris Masone3c3f6a12011-07-01 10:01:41 -070088 EXPECT_TRUE(IsDeviceRegistered(mock_device_, Device::kEthernet));
89 EXPECT_TRUE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Darin Petkov6f9eaa32011-08-09 15:26:44 -070090 EXPECT_TRUE(IsDeviceRegistered(mock_device3_, Device::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -070091}
92
93TEST_F(ManagerTest, DeviceDeregistration) {
Chris Masone3c3f6a12011-07-01 10:01:41 -070094 ON_CALL(*mock_device_.get(), TechnologyIs(Device::kEthernet))
95 .WillByDefault(Return(true));
96 ON_CALL(*mock_device2_.get(), TechnologyIs(Device::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -070097 .WillByDefault(Return(true));
98
Chris Masone3c3f6a12011-07-01 10:01:41 -070099 manager_.RegisterDevice(mock_device_.get());
100 manager_.RegisterDevice(mock_device2_.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700101
Chris Masone3c3f6a12011-07-01 10:01:41 -0700102 ASSERT_TRUE(IsDeviceRegistered(mock_device_, Device::kEthernet));
103 ASSERT_TRUE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700104
mukesh agrawal5029c6c2011-08-25 11:12:40 -0700105 EXPECT_CALL(*mock_device_.get(), Stop());
Chris Masone3c3f6a12011-07-01 10:01:41 -0700106 manager_.DeregisterDevice(mock_device_.get());
107 EXPECT_FALSE(IsDeviceRegistered(mock_device_, Device::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700108
mukesh agrawal5029c6c2011-08-25 11:12:40 -0700109 EXPECT_CALL(*mock_device2_.get(), Stop());
Chris Masone3c3f6a12011-07-01 10:01:41 -0700110 manager_.DeregisterDevice(mock_device2_.get());
111 EXPECT_FALSE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700112}
113
114TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9be4a9d2011-05-16 15:44:09 -0700115 scoped_refptr<MockService> mock_service(
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700116 new NiceMock<MockService>(&control_interface_,
Chris Masonea82b7112011-05-25 15:16:29 -0700117 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700118 &manager_));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700119 scoped_refptr<MockService> mock_service2(
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700120 new NiceMock<MockService>(&control_interface_,
Chris Masonea82b7112011-05-25 15:16:29 -0700121 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700122 &manager_));
123 string service1_name(mock_service->UniqueName());
124 string service2_name(mock_service2->UniqueName());
125
126 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
127 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700128 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700129 .WillRepeatedly(Return(service2_name));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700130
Chris Masonee0dea762011-06-09 09:06:03 -0700131 manager_.RegisterService(mock_service);
132 manager_.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700133
Chris Masone6791a432011-07-12 13:23:19 -0700134 vector<string> rpc_ids = manager_.EnumerateAvailableServices();
135 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700136 EXPECT_EQ(2, ids.size());
137 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
138 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700139
mukesh agrawal51a7e932011-07-27 16:18:26 -0700140 EXPECT_TRUE(manager_.FindService(service1_name).get() != NULL);
141 EXPECT_TRUE(manager_.FindService(service2_name).get() != NULL);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700142}
143
Chris Masonea8a2c252011-06-27 22:16:30 -0700144TEST_F(ManagerTest, GetProperties) {
145 map<string, ::DBus::Variant> props;
146 Error error(Error::kInvalidProperty, "");
147 {
148 ::DBus::Error dbus_error;
149 string expected("portal_list");
Chris Masone27c4aa52011-07-02 13:10:14 -0700150 manager_.store()->SetStringProperty(flimflam::kCheckPortalListProperty,
151 expected,
152 &error);
153 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700154 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
155 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
156 expected);
157 }
158 {
159 ::DBus::Error dbus_error;
160 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -0700161 manager_.store()->SetBoolProperty(flimflam::kOfflineModeProperty,
162 expected,
163 &error);
164 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700165 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
166 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
167 expected);
168 }
169}
170
Chris Masone3c3f6a12011-07-01 10:01:41 -0700171TEST_F(ManagerTest, GetDevicesProperty) {
172 manager_.RegisterDevice(mock_device_.get());
173 manager_.RegisterDevice(mock_device2_.get());
174 {
175 map<string, ::DBus::Variant> props;
176 ::DBus::Error dbus_error;
177 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -0700178 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700179 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
180 Strings devices =
181 props[flimflam::kDevicesProperty].operator vector<string>();
182 EXPECT_EQ(2, devices.size());
183 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700184}
185
Chris Masone6791a432011-07-12 13:23:19 -0700186TEST_F(ManagerTest, MoveService) {
187 // I want to ensure that the Profiles are managing this Service object
188 // lifetime properly, so I can't hold a ref to it here.
Chris Masone7df0c672011-07-15 10:24:54 -0700189 ProfileRefPtr profile(
190 new MockProfile(&control_interface_, &glib_, &manager_, ""));
mukesh agrawal51a7e932011-07-27 16:18:26 -0700191 string service_name;
Chris Masone6791a432011-07-12 13:23:19 -0700192 {
193 ServiceRefPtr s2(
194 new MockService(&control_interface_,
195 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700196 &manager_));
Chris Masone6791a432011-07-12 13:23:19 -0700197 profile->AdoptService(s2);
198 s2->set_profile(profile);
mukesh agrawal51a7e932011-07-27 16:18:26 -0700199 service_name = s2->UniqueName();
Chris Masone6791a432011-07-12 13:23:19 -0700200 }
201
202 // Now, move the |service| to another profile.
mukesh agrawal51a7e932011-07-27 16:18:26 -0700203 manager_.MoveToActiveProfile(profile, profile->FindService(service_name));
Chris Masone6791a432011-07-12 13:23:19 -0700204
205 // Force destruction of the original Profile, to ensure that the Service
206 // is kept alive and populated with data.
207 profile = NULL;
208 {
mukesh agrawal51a7e932011-07-27 16:18:26 -0700209 ServiceRefPtr serv(manager_.ActiveProfile()->FindService(service_name));
Chris Masone6791a432011-07-12 13:23:19 -0700210 ASSERT_TRUE(serv.get() != NULL);
211 Error error(Error::kInvalidProperty, "");
212 ::DBus::Error dbus_error;
213 map<string, ::DBus::Variant> props;
214 bool expected = true;
215 serv->store()->SetBoolProperty(flimflam::kAutoConnectProperty,
216 expected,
217 &error);
218 DBusAdaptor::GetProperties(serv->store(), &props, &dbus_error);
219 ASSERT_TRUE(ContainsKey(props, flimflam::kAutoConnectProperty));
220 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
221 expected);
222 }
223}
224
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700225TEST_F(ManagerTest, Dispatch) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700226 {
227 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700228 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700229 flimflam::kOfflineModeProperty,
230 PropertyStoreTest::kBoolV,
231 &error));
232 }
233 {
234 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700235 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700236 flimflam::kCountryProperty,
237 PropertyStoreTest::kStringV,
238 &error));
239 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700240 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700241 {
242 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700243 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700244 flimflam::kCountryProperty,
245 PropertyStoreTest::kBoolV,
246 &error));
247 EXPECT_EQ(invalid_args_, error.name());
248 }
249 {
250 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700251 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700252 flimflam::kOfflineModeProperty,
253 PropertyStoreTest::kStringV,
254 &error));
255 EXPECT_EQ(invalid_args_, error.name());
256 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700257 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700258 {
259 ::DBus::Error error;
260 EXPECT_FALSE(DBusAdaptor::DispatchOnType(
Chris Masone27c4aa52011-07-02 13:10:14 -0700261 manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700262 flimflam::kEnabledTechnologiesProperty,
263 PropertyStoreTest::kStringsV,
264 &error));
265 EXPECT_EQ(invalid_args_, error.name());
266 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700267}
268
Chris Masone9be4a9d2011-05-16 15:44:09 -0700269} // namespace shill