blob: a659579ad69a207cad32f33c82a1bcddc093ceec [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
11#include <base/callback_old.h>
12#include <base/logging.h>
13#include <base/memory/ref_counted.h>
14#include <base/message_loop.h>
Chris Masone6791a432011-07-12 13:23:19 -070015#include <base/stl_util-inl.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <chromeos/dbus/service_constants.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070017#include <gtest/gtest.h>
18#include <gmock/gmock.h>
19
Chris Masoned7732e42011-05-20 11:08:56 -070020#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070021#include "shill/mock_device.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070022#include "shill/mock_glib.h"
23#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070024#include "shill/mock_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070025#include "shill/property_store_unittest.h"
26#include "shill/shill_event.h"
27
28using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070029using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070030using std::string;
31using std::vector;
32
Chris Masone9be4a9d2011-05-16 15:44:09 -070033namespace shill {
34using ::testing::Test;
35using ::testing::_;
36using ::testing::NiceMock;
37using ::testing::Return;
Chris Masone9be4a9d2011-05-16 15:44:09 -070038
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070040 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070041 ManagerTest()
42 : factory_(this),
43 mock_device_(new NiceMock<MockDevice>(&control_interface_,
44 &dispatcher_,
45 &manager_,
46 "null0",
47 -1)),
48 mock_device2_(new NiceMock<MockDevice>(&control_interface_,
49 &dispatcher_,
50 &manager_,
51 "null1",
52 -1)) {
53 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070054 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -070055
Chris Masone2b105542011-06-22 10:58:09 -070056 bool IsDeviceRegistered(const DeviceRefPtr &device, Device::Technology tech) {
Chris Masonec1e50412011-06-07 13:04:53 -070057 vector<DeviceRefPtr> devices;
Chris Masone9be4a9d2011-05-16 15:44:09 -070058 manager_.FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -070059 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -070060 }
61
Paul Stewartf1ce5d22011-05-19 13:10:20 -070062 protected:
Chris Masone9be4a9d2011-05-16 15:44:09 -070063 ScopedRunnableMethodFactory<ManagerTest> factory_;
Chris Masone3c3f6a12011-07-01 10:01:41 -070064 scoped_refptr<MockDevice> mock_device_;
65 scoped_refptr<MockDevice> mock_device2_;
Chris Masone9be4a9d2011-05-16 15:44:09 -070066};
67
Chris Masone3bd3c8c2011-06-13 08:20:26 -070068TEST_F(ManagerTest, Contains) {
Chris Masone27c4aa52011-07-02 13:10:14 -070069 EXPECT_TRUE(manager_.store()->Contains(flimflam::kStateProperty));
70 EXPECT_FALSE(manager_.store()->Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -070071}
72
Chris Masone9be4a9d2011-05-16 15:44:09 -070073TEST_F(ManagerTest, DeviceRegistration) {
Chris Masone3c3f6a12011-07-01 10:01:41 -070074 ON_CALL(*mock_device_.get(), TechnologyIs(Device::kEthernet))
75 .WillByDefault(Return(true));
76 ON_CALL(*mock_device2_.get(), TechnologyIs(Device::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -070077 .WillByDefault(Return(true));
78
Chris Masone3c3f6a12011-07-01 10:01:41 -070079 manager_.RegisterDevice(mock_device_.get());
80 manager_.RegisterDevice(mock_device2_.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -070081
Chris Masone3c3f6a12011-07-01 10:01:41 -070082 EXPECT_TRUE(IsDeviceRegistered(mock_device_, Device::kEthernet));
83 EXPECT_TRUE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -070084}
85
86TEST_F(ManagerTest, DeviceDeregistration) {
Chris Masone3c3f6a12011-07-01 10:01:41 -070087 ON_CALL(*mock_device_.get(), TechnologyIs(Device::kEthernet))
88 .WillByDefault(Return(true));
89 ON_CALL(*mock_device2_.get(), TechnologyIs(Device::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -070090 .WillByDefault(Return(true));
91
Chris Masone3c3f6a12011-07-01 10:01:41 -070092 manager_.RegisterDevice(mock_device_.get());
93 manager_.RegisterDevice(mock_device2_.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -070094
Chris Masone3c3f6a12011-07-01 10:01:41 -070095 ASSERT_TRUE(IsDeviceRegistered(mock_device_, Device::kEthernet));
96 ASSERT_TRUE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -070097
Chris Masone3c3f6a12011-07-01 10:01:41 -070098 manager_.DeregisterDevice(mock_device_.get());
99 EXPECT_FALSE(IsDeviceRegistered(mock_device_, Device::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700100
Chris Masone3c3f6a12011-07-01 10:01:41 -0700101 manager_.DeregisterDevice(mock_device2_.get());
102 EXPECT_FALSE(IsDeviceRegistered(mock_device2_, Device::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700103}
104
105TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9be4a9d2011-05-16 15:44:09 -0700106 scoped_refptr<MockService> mock_service(
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700107 new NiceMock<MockService>(&control_interface_,
Chris Masonea82b7112011-05-25 15:16:29 -0700108 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700109 &manager_));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700110 scoped_refptr<MockService> mock_service2(
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700111 new NiceMock<MockService>(&control_interface_,
Chris Masonea82b7112011-05-25 15:16:29 -0700112 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700113 &manager_));
114 string service1_name(mock_service->UniqueName());
115 string service2_name(mock_service2->UniqueName());
116
117 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
118 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700119 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700120 .WillRepeatedly(Return(service2_name));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700121
Chris Masonee0dea762011-06-09 09:06:03 -0700122 manager_.RegisterService(mock_service);
123 manager_.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700124
Chris Masone6791a432011-07-12 13:23:19 -0700125 vector<string> rpc_ids = manager_.EnumerateAvailableServices();
126 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700127 EXPECT_EQ(2, ids.size());
128 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
129 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700130
mukesh agrawal51a7e932011-07-27 16:18:26 -0700131 EXPECT_TRUE(manager_.FindService(service1_name).get() != NULL);
132 EXPECT_TRUE(manager_.FindService(service2_name).get() != NULL);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700133}
134
Chris Masonea8a2c252011-06-27 22:16:30 -0700135TEST_F(ManagerTest, GetProperties) {
136 map<string, ::DBus::Variant> props;
137 Error error(Error::kInvalidProperty, "");
138 {
139 ::DBus::Error dbus_error;
140 string expected("portal_list");
Chris Masone27c4aa52011-07-02 13:10:14 -0700141 manager_.store()->SetStringProperty(flimflam::kCheckPortalListProperty,
142 expected,
143 &error);
144 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700145 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
146 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
147 expected);
148 }
149 {
150 ::DBus::Error dbus_error;
151 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -0700152 manager_.store()->SetBoolProperty(flimflam::kOfflineModeProperty,
153 expected,
154 &error);
155 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700156 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
157 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
158 expected);
159 }
160}
161
Chris Masone3c3f6a12011-07-01 10:01:41 -0700162TEST_F(ManagerTest, GetDevicesProperty) {
163 manager_.RegisterDevice(mock_device_.get());
164 manager_.RegisterDevice(mock_device2_.get());
165 {
166 map<string, ::DBus::Variant> props;
167 ::DBus::Error dbus_error;
168 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -0700169 DBusAdaptor::GetProperties(manager_.store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700170 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
171 Strings devices =
172 props[flimflam::kDevicesProperty].operator vector<string>();
173 EXPECT_EQ(2, devices.size());
174 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700175}
176
Chris Masone6791a432011-07-12 13:23:19 -0700177TEST_F(ManagerTest, MoveService) {
178 // I want to ensure that the Profiles are managing this Service object
179 // lifetime properly, so I can't hold a ref to it here.
Chris Masone7df0c672011-07-15 10:24:54 -0700180 ProfileRefPtr profile(
181 new MockProfile(&control_interface_, &glib_, &manager_, ""));
mukesh agrawal51a7e932011-07-27 16:18:26 -0700182 string service_name;
Chris Masone6791a432011-07-12 13:23:19 -0700183 {
184 ServiceRefPtr s2(
185 new MockService(&control_interface_,
186 &dispatcher_,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700187 &manager_));
Chris Masone6791a432011-07-12 13:23:19 -0700188 profile->AdoptService(s2);
189 s2->set_profile(profile);
mukesh agrawal51a7e932011-07-27 16:18:26 -0700190 service_name = s2->UniqueName();
Chris Masone6791a432011-07-12 13:23:19 -0700191 }
192
193 // Now, move the |service| to another profile.
mukesh agrawal51a7e932011-07-27 16:18:26 -0700194 manager_.MoveToActiveProfile(profile, profile->FindService(service_name));
Chris Masone6791a432011-07-12 13:23:19 -0700195
196 // Force destruction of the original Profile, to ensure that the Service
197 // is kept alive and populated with data.
198 profile = NULL;
199 {
mukesh agrawal51a7e932011-07-27 16:18:26 -0700200 ServiceRefPtr serv(manager_.ActiveProfile()->FindService(service_name));
Chris Masone6791a432011-07-12 13:23:19 -0700201 ASSERT_TRUE(serv.get() != NULL);
202 Error error(Error::kInvalidProperty, "");
203 ::DBus::Error dbus_error;
204 map<string, ::DBus::Variant> props;
205 bool expected = true;
206 serv->store()->SetBoolProperty(flimflam::kAutoConnectProperty,
207 expected,
208 &error);
209 DBusAdaptor::GetProperties(serv->store(), &props, &dbus_error);
210 ASSERT_TRUE(ContainsKey(props, flimflam::kAutoConnectProperty));
211 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
212 expected);
213 }
214}
215
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700216TEST_F(ManagerTest, Dispatch) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700217 {
218 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700219 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700220 flimflam::kOfflineModeProperty,
221 PropertyStoreTest::kBoolV,
222 &error));
223 }
224 {
225 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700226 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700227 flimflam::kCountryProperty,
228 PropertyStoreTest::kStringV,
229 &error));
230 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700231 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700232 {
233 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700234 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700235 flimflam::kCountryProperty,
236 PropertyStoreTest::kBoolV,
237 &error));
238 EXPECT_EQ(invalid_args_, error.name());
239 }
240 {
241 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700242 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700243 flimflam::kOfflineModeProperty,
244 PropertyStoreTest::kStringV,
245 &error));
246 EXPECT_EQ(invalid_args_, error.name());
247 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700248 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700249 {
250 ::DBus::Error error;
251 EXPECT_FALSE(DBusAdaptor::DispatchOnType(
Chris Masone27c4aa52011-07-02 13:10:14 -0700252 manager_.store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700253 flimflam::kEnabledTechnologiesProperty,
254 PropertyStoreTest::kStringsV,
255 &error));
256 EXPECT_EQ(invalid_args_, error.name());
257 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700258}
259
Chris Masone9be4a9d2011-05-16 15:44:09 -0700260} // namespace shill