blob: efa4b86dd1fc6752e1f08885262e7785fc3291d2 [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// 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>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070012#include <base/memory/scoped_temp_dir.h>
Chris Masone6791a432011-07-12 13:23:19 -070013#include <base/stl_util-inl.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070014#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070016#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070017#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070018
mukesh agrawal32399322011-09-01 10:53:43 -070019#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070020#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070021#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070022#include "shill/glib.h"
23#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070024#include "shill/key_value_store.h"
mukesh agrawal32399322011-09-01 10:53:43 -070025#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080026#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070027#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070028#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080029#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070030#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000031#include "shill/mock_metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070032#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070033#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070034#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070035#include "shill/mock_wifi.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070037#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070038#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039
40using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070041using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042using std::string;
43using std::vector;
44
Chris Masone9be4a9d2011-05-16 15:44:09 -070045namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070046using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070047using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080048using ::testing::ContainerEq;
Paul Stewart22aa71b2011-09-16 12:15:11 -070049using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070050using ::testing::NiceMock;
51using ::testing::Return;
Gaurav Shah435de2c2011-11-17 19:01:07 -080052using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080053using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070054using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070055
Chris Masone3bd3c8c2011-06-13 08:20:26 -070056class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070057 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070058 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070059 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070060 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080061 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070062 manager(),
63 "wifi0",
64 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080065 4)),
66 device_info_(new NiceMock<MockDeviceInfo>(
67 control_interface(),
68 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080069 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080070 reinterpret_cast<Manager*>(NULL))),
71 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070072 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
73 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080074 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070075 manager(),
76 "null0",
77 "addr0",
78 0));
79 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
80 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080081 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070082 manager(),
83 "null1",
84 "addr1",
85 1));
86 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
87 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080088 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070089 manager(),
90 "null2",
91 "addr2",
92 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080093 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
94 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080095 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -080096 manager(),
97 "null3",
98 "addr3",
99 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700100 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800101
102 // Replace the manager's adaptor with a quieter one, and one
103 // we can do EXPECT*() against. Passes ownership.
104 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700105 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700106 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700107
Paul Stewartfdd16072011-09-16 12:41:35 -0700108 bool IsDeviceRegistered(const DeviceRefPtr &device,
109 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700110 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700111 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700112 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700113 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700114 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700115
Paul Stewarta849a3d2011-11-03 05:54:09 -0700116 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
117 manager->profiles_.push_back(profile);
118 }
119
Paul Stewart75225512012-01-26 22:51:33 -0800120 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
121 return manager->ephemeral_profile_;
122 }
123
Chris Masone6515aab2011-10-12 16:19:09 -0700124 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
125 Profile::Identifier id("rather", "irrelevant");
126 scoped_ptr<Profile> profile(new Profile(control_interface(),
127 manager,
128 id,
129 "",
130 false));
131 FilePath final_path(storage_path());
132 final_path = final_path.Append("test.profile");
133 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
134 storage->set_path(final_path);
135 if (!storage->Open())
136 return NULL;
137 profile->set_storage(storage.release()); // Passes ownership.
138 return profile.release();
139 }
140
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700141 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
142 const string &profile_identifier,
143 const string &service_name) {
144 GLib glib;
145 KeyFileStore store(&glib);
146 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
147 return store.Open() &&
148 store.SetString(service_name, "rather", "irrelevant") &&
149 store.Close();
150 }
151
152 Error::Type TestCreateProfile(Manager *manager, const string &name) {
153 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800154 string path;
155 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700156 return error.type();
157 }
158
159 Error::Type TestPopAnyProfile(Manager *manager) {
160 Error error;
161 manager->PopAnyProfile(&error);
162 return error.type();
163 }
164
165 Error::Type TestPopProfile(Manager *manager, const string &name) {
166 Error error;
167 manager->PopProfile(name, &error);
168 return error.type();
169 }
170
171 Error::Type TestPushProfile(Manager *manager, const string &name) {
172 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800173 string path;
174 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700175 return error.type();
176 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000177
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700178 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000179 typedef scoped_refptr<MockService> MockServiceRefPtr;
180
181 MockServiceRefPtr MakeAutoConnectableService() {
182 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
183 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800184 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000185 manager());
186 service->MakeFavorite();
187 service->set_connectable(true);
188 return service;
189 }
190
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700191 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700192 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800193 scoped_ptr<MockDeviceInfo> device_info_;
194
195 // This pointer is owned by the manager, and only tracked here for EXPECT*()
196 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700197};
198
Paul Stewart22aa71b2011-09-16 12:15:11 -0700199bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
200 return (svc0.get() == manager()->services_[0].get() &&
201 svc1.get() == manager()->services_[1].get());
202}
203
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700204TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700205 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
206 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700207}
208
Chris Masone9be4a9d2011-05-16 15:44:09 -0700209TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700210 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700211 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700212 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700213 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700214 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700215 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700216
Paul Stewart22aa71b2011-09-16 12:15:11 -0700217 manager()->RegisterDevice(mock_devices_[0]);
218 manager()->RegisterDevice(mock_devices_[1]);
219 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700220
Paul Stewart22aa71b2011-09-16 12:15:11 -0700221 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
222 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
223 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700224}
225
Paul Stewarta41e38d2011-11-11 07:47:29 -0800226TEST_F(ManagerTest, DeviceRegistrationAndStart) {
227 manager()->running_ = true;
228 mock_devices_[0]->powered_ = true;
229 mock_devices_[1]->powered_ = false;
230 EXPECT_CALL(*mock_devices_[0].get(), Start())
231 .Times(1);
232 EXPECT_CALL(*mock_devices_[1].get(), Start())
233 .Times(0);
234 manager()->RegisterDevice(mock_devices_[0]);
235 manager()->RegisterDevice(mock_devices_[1]);
236}
237
238TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
239 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
240 DeviceRefPtr device_ref(mock_devices_[0].get());
241 AdoptProfile(manager(), profile); // Passes ownership.
242 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
243 EXPECT_CALL(*profile, Save());
244 manager()->RegisterDevice(mock_devices_[0]);
245}
246
Chris Masone9be4a9d2011-05-16 15:44:09 -0700247TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700248 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700249 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700250 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700251 .WillByDefault(Return(true));
252
Gaurav Shah435de2c2011-11-17 19:01:07 -0800253 manager()->RegisterDevice(mock_devices_[0]);
254 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700255
Paul Stewart22aa71b2011-09-16 12:15:11 -0700256 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
257 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700258
Paul Stewart22aa71b2011-09-16 12:15:11 -0700259 EXPECT_CALL(*mock_devices_[0].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800260 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700261 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700262
Paul Stewart22aa71b2011-09-16 12:15:11 -0700263 EXPECT_CALL(*mock_devices_[1].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800264 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700265 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700266}
267
268TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700269 // It's much easier and safer to use a real GLib for this test.
270 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700271 Manager manager(control_interface(),
272 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800273 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700274 &glib,
275 run_path(),
276 storage_path(),
277 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700278 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
279 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700280 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700281
Chris Masone9be4a9d2011-05-16 15:44:09 -0700282 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700283 new NiceMock<MockService>(control_interface(),
284 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800285 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700286 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700287 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700288 new NiceMock<MockService>(control_interface(),
289 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800290 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700291 &manager));
mukesh agrawal51a7e932011-07-27 16:18:26 -0700292 string service1_name(mock_service->UniqueName());
293 string service2_name(mock_service2->UniqueName());
294
295 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
296 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700297 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700298 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700299 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700300 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700301 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700302
Chris Masone9d779932011-08-25 16:33:41 -0700303 manager.RegisterService(mock_service);
304 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700305
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800306 Error error;
307 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700308 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700309 EXPECT_EQ(2, ids.size());
310 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
311 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700312
Chris Masone9d779932011-08-25 16:33:41 -0700313 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
314 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
315
316 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700317}
318
Chris Masone6515aab2011-10-12 16:19:09 -0700319TEST_F(ManagerTest, RegisterKnownService) {
320 // It's much easier and safer to use a real GLib for this test.
321 GLib glib;
322 Manager manager(control_interface(),
323 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800324 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700325 &glib,
326 run_path(),
327 storage_path(),
328 string());
329 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
330 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700331 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700332 {
333 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
334 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800335 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700336 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700337 ASSERT_TRUE(profile->AdoptService(service1));
338 ASSERT_TRUE(profile->ContainsService(service1));
339 } // Force destruction of service1.
340
341 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
342 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800343 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700344 &manager));
345 manager.RegisterService(service2);
346 EXPECT_EQ(service2->profile().get(), profile.get());
347 manager.Stop();
348}
349
350TEST_F(ManagerTest, RegisterUnknownService) {
351 // It's much easier and safer to use a real GLib for this test.
352 GLib glib;
353 Manager manager(control_interface(),
354 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800355 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700356 &glib,
357 run_path(),
358 storage_path(),
359 string());
360 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
361 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700362 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700363 {
364 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
365 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800366 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700367 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700368 ASSERT_TRUE(profile->AdoptService(service1));
369 ASSERT_TRUE(profile->ContainsService(service1));
370 } // Force destruction of service1.
371 scoped_refptr<MockService> mock_service2(
372 new NiceMock<MockService>(control_interface(),
373 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800374 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700375 &manager));
376 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
377 .WillRepeatedly(Return(mock_service2->UniqueName()));
378 manager.RegisterService(mock_service2);
379 EXPECT_NE(mock_service2->profile().get(), profile.get());
380 manager.Stop();
381}
382
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000383TEST_F(ManagerTest, DeregisterUnregisteredService) {
384 // WiFi assumes that it can deregister a service that is not
385 // registered. (E.g. a hidden service can be deregistered when it
386 // loses its last endpoint, and again when WiFi is Stop()-ed.)
387 //
388 // So test that doing so doesn't cause a crash.
389 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
390 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800391 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000392 manager());
393 manager()->DeregisterService(service);
394}
395
Chris Masonea8a2c252011-06-27 22:16:30 -0700396TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700397 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700398 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700399 map<string, ::DBus::Variant> props;
400 Error error(Error::kInvalidProperty, "");
401 {
402 ::DBus::Error dbus_error;
403 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700404 manager()->mutable_store()->SetStringProperty(
405 flimflam::kCheckPortalListProperty,
406 expected,
407 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700408 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700409 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
410 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
411 expected);
412 }
413 {
414 ::DBus::Error dbus_error;
415 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700416 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
417 expected,
418 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700419 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700420 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
421 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
422 expected);
423 }
424}
425
Chris Masone3c3f6a12011-07-01 10:01:41 -0700426TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700427 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700428 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800429 manager()->RegisterDevice(mock_devices_[0]);
430 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700431 {
432 map<string, ::DBus::Variant> props;
433 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700434 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700435 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
436 Strings devices =
437 props[flimflam::kDevicesProperty].operator vector<string>();
438 EXPECT_EQ(2, devices.size());
439 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700440}
441
Chris Masone6791a432011-07-12 13:23:19 -0700442TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700443 Manager manager(control_interface(),
444 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800445 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700446 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700447 run_path(),
448 storage_path(),
449 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700450 scoped_refptr<MockService> s2(new MockService(control_interface(),
451 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800452 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700453 &manager));
454 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700455 {
Chris Masone6515aab2011-10-12 16:19:09 -0700456 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700457 ProfileRefPtr profile(
458 new Profile(control_interface(), &manager, id, "", false));
459 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700460 // Say we don't have |s2| the first time asked, then that we do.
461 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
462 .WillOnce(Return(false))
463 .WillRepeatedly(Return(true));
464 EXPECT_CALL(*storage, Flush())
465 .Times(AnyNumber())
466 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700467 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700468 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700469 }
Chris Masone6515aab2011-10-12 16:19:09 -0700470 // Create a profile that already has |s2| in it.
471 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
472 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700473
Chris Masone6515aab2011-10-12 16:19:09 -0700474 // Now, move the Service |s2| to another profile.
475 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
476 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700477
478 // Force destruction of the original Profile, to ensure that the Service
479 // is kept alive and populated with data.
480 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700481 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700482 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700483}
484
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800485TEST_F(ManagerTest, SetProfileForService) {
486 scoped_refptr<MockProfile> profile0(
487 new MockProfile(control_interface(), manager(), ""));
488 string profile_name0("profile0");
489 EXPECT_CALL(*profile0, GetRpcIdentifier())
490 .WillRepeatedly(Return(profile_name0));
491 AdoptProfile(manager(), profile0);
492 scoped_refptr<MockService> service(new MockService(control_interface(),
493 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800494 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800495 manager()));
496 service->set_profile(profile0);
497
498 {
499 Error error;
500 manager()->SetProfileForService(service, "foo", &error);
501 EXPECT_EQ(Error::kInvalidArguments, error.type());
502 EXPECT_EQ("Unknown Profile requested for Service", error.message());
503 }
504
505 {
506 Error error;
507 manager()->SetProfileForService(service, profile_name0, &error);
508 EXPECT_EQ(Error::kInvalidArguments, error.type());
509 EXPECT_EQ("Service is already connected to this profile", error.message());
510 }
511
512 scoped_refptr<MockProfile> profile1(
513 new MockProfile(control_interface(), manager(), ""));
514 string profile_name1("profile1");
515 EXPECT_CALL(*profile1, GetRpcIdentifier())
516 .WillRepeatedly(Return(profile_name1));
517 AdoptProfile(manager(), profile1);
518
519 {
520 Error error;
521 EXPECT_CALL(*profile1, AdoptService(_))
522 .WillOnce(Return(true));
523 EXPECT_CALL(*profile0, AbandonService(_))
524 .WillOnce(Return(true));
525 manager()->SetProfileForService(service, profile_name1, &error);
526 EXPECT_TRUE(error.IsSuccess());
527 }
528}
529
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700530TEST_F(ManagerTest, CreateProfile) {
531 // It's much easier to use real Glib here since we want the storage
532 // side-effects.
533 GLib glib;
534 ScopedTempDir temp_dir;
535 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
536
537 Manager manager(control_interface(),
538 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800539 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700540 &glib,
541 run_path(),
542 storage_path(),
543 temp_dir.path().value());
544
545 // Invalid name should be rejected.
546 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
547
548 // Valid name is still rejected because we can't create a profile
549 // that doesn't have a user component. Such profile names are
550 // reserved for the single DefaultProfile the manager creates
551 // at startup.
552 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, "valid"));
553
554 // We should succeed in creating a valid user profile.
555 const char kProfile[] = "~user/profile";
556 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
557
558 // We should fail in creating it a second time (already exists).
559 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
560}
561
562TEST_F(ManagerTest, PushPopProfile) {
563 // It's much easier to use real Glib in creating a Manager for this
564 // test here since we want the storage side-effects.
565 GLib glib;
566 ScopedTempDir temp_dir;
567 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
568 Manager manager(control_interface(),
569 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800570 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700571 &glib,
572 run_path(),
573 storage_path(),
574 temp_dir.path().value());
575
576 // Pushing an invalid profile should fail.
577 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
578
579 // Pushing a default profile name should fail.
580 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, "default"));
581
582 const char kProfile0[] = "~user/profile0";
583 const char kProfile1[] = "~user/profile1";
584
585 // Create a couple of profiles.
586 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
587 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
588
589 // Push these profiles on the stack.
590 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
591 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
592
593 // Pushing a profile a second time should fail.
594 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
595 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
596
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800597 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700598 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800599 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700600
601 // Make sure a profile name that doesn't exist fails.
602 const char kProfile2Id[] = "profile2";
603 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
604 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
605
606 // Create a new service, with a specific storage name.
607 scoped_refptr<MockService> service(
608 new NiceMock<MockService>(control_interface(),
609 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800610 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700611 &manager));
612 const char kServiceName[] = "service_storage_name";
613 EXPECT_CALL(*service.get(), GetStorageIdentifier())
614 .WillRepeatedly(Return(kServiceName));
615 EXPECT_CALL(*service.get(), Load(_))
616 .WillRepeatedly(Return(true));
617
618 // Add this service to the manager -- it should end up in the ephemeral
619 // profile.
620 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800621 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700622
623 // Create storage for a profile that contains the service storage name.
624 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
625 kServiceName));
626
627 // When we push the profile, the service should move away from the
628 // ephemeral profile to this new profile since it has an entry for
629 // this service.
630 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800631 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700632 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
633
634 // Insert another profile that should supersede ownership of the service.
635 const char kProfile3Id[] = "profile3";
636 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
637 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
638 kServiceName));
639 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
640 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
641
642 // Popping an invalid profile name should fail.
643 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
644
645 // Popping an profile that is not at the top of the stack should fail.
646 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
647
648 // Popping the top profile should succeed.
649 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
650
651 // Moreover the service should have switched profiles to profile 2.
652 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
653
654 // Popping the top profile should succeed.
655 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
656
657 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800658 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700659
660 // Pop the remaining two services off the stack.
661 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
662 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
663
664 // Next pop should fail with "stack is empty".
665 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
666}
667
Paul Stewart75225512012-01-26 22:51:33 -0800668// Use this matcher instead of passing RefPtrs directly into the arguments
669// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
670// system teardown.
671MATCHER_P(IsRefPtrTo, ref_address, "") {
672 return arg.get() == ref_address;
673}
674
675TEST_F(ManagerTest, HandleProfileEntryDeletion) {
676 MockServiceRefPtr s_not_in_profile(
677 new NiceMock<MockService>(control_interface(),
678 dispatcher(),
679 metrics(),
680 manager()));
681 MockServiceRefPtr s_not_in_group(
682 new NiceMock<MockService>(control_interface(),
683 dispatcher(),
684 metrics(),
685 manager()));
686 MockServiceRefPtr s_configure_fail(
687 new NiceMock<MockService>(control_interface(),
688 dispatcher(),
689 metrics(),
690 manager()));
691 MockServiceRefPtr s_configure_succeed(
692 new NiceMock<MockService>(control_interface(),
693 dispatcher(),
694 metrics(),
695 manager()));
696
697 string entry_name("entry_name");
698 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
699 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
700 .WillRepeatedly(Return("not_entry_name"));
701 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
702 .WillRepeatedly(Return(entry_name));
703 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
704 .WillRepeatedly(Return(entry_name));
705
706 manager()->RegisterService(s_not_in_profile);
707 manager()->RegisterService(s_not_in_group);
708 manager()->RegisterService(s_configure_fail);
709 manager()->RegisterService(s_configure_succeed);
710
711 scoped_refptr<MockProfile> profile0(
712 new StrictMock<MockProfile>(control_interface(), manager(), ""));
713 scoped_refptr<MockProfile> profile1(
714 new StrictMock<MockProfile>(control_interface(), manager(), ""));
715
716 s_not_in_group->set_profile(profile1);
717 s_configure_fail->set_profile(profile1);
718 s_configure_succeed->set_profile(profile1);
719
720 AdoptProfile(manager(), profile0);
721 AdoptProfile(manager(), profile1);
722
723 // No services are a member of this profile.
724 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
725
726 // No services that are members of this profile have this entry name.
727 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
728
729 // Only services that are members of the profile and group will be abandoned.
730 EXPECT_CALL(*profile1.get(),
731 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
732 EXPECT_CALL(*profile1.get(),
733 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
734 EXPECT_CALL(*profile1.get(),
735 AbandonService(IsRefPtrTo(s_configure_fail.get())))
736 .WillOnce(Return(true));
737 EXPECT_CALL(*profile1.get(),
738 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
739 .WillOnce(Return(true));
740
741 // Never allow services to re-join profile1.
742 EXPECT_CALL(*profile1.get(), ConfigureService(_))
743 .WillRepeatedly(Return(false));
744
745 // Only allow one of the members of the profile and group to successfully
746 // join profile0.
747 EXPECT_CALL(*profile0.get(),
748 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
749 EXPECT_CALL(*profile0.get(),
750 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
751 EXPECT_CALL(*profile0.get(),
752 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
753 .WillOnce(Return(false));
754 EXPECT_CALL(*profile0.get(),
755 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
756 .WillOnce(Return(true));
757
758 // Expect the failed-to-configure service to have Unload() called on it.
759 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
760 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
761 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
762 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
763
764 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
765
766 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
767 EXPECT_EQ(profile1, s_not_in_group->profile());
768 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
769
770 // Since we are using a MockProfile, the profile does not actually change,
771 // since ConfigureService was not actually called on the service.
772 EXPECT_EQ(profile1, s_configure_succeed->profile());
773}
774
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800775TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700776 {
777 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800778 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
779 flimflam::kOfflineModeProperty,
780 PropertyStoreTest::kBoolV,
781 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700782 }
783 {
784 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800785 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
786 flimflam::kCountryProperty,
787 PropertyStoreTest::kStringV,
788 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700789 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700790 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700791 {
792 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800793 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
794 flimflam::kCountryProperty,
795 PropertyStoreTest::kBoolV,
796 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700797 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700798 }
799 {
800 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800801 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
802 flimflam::kOfflineModeProperty,
803 PropertyStoreTest::kStringV,
804 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700805 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700806 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700807 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700808 {
809 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800810 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700811 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700812 flimflam::kEnabledTechnologiesProperty,
813 PropertyStoreTest::kStringsV,
814 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700815 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700816 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700817}
818
mukesh agrawal32399322011-09-01 10:53:43 -0700819TEST_F(ManagerTest, RequestScan) {
820 {
821 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700822 manager()->RegisterDevice(mock_devices_[0].get());
823 manager()->RegisterDevice(mock_devices_[1].get());
824 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700825 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700826 EXPECT_CALL(*mock_devices_[0], Scan(_));
827 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700828 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700829 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -0700830 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700831 }
832
833 {
834 Error error;
Chris Masone9d779932011-08-25 16:33:41 -0700835 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700836 EXPECT_EQ(Error::kInvalidArguments, error.type());
837 }
838}
839
Darin Petkovb65c2452012-02-23 15:17:06 +0100840TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700841 KeyValueStore args;
842 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100843 manager()->GetService(args, &e);
844 EXPECT_EQ(Error::kInvalidArguments, e.type());
845 EXPECT_EQ("must specify service type", e.message());
846}
847
848TEST_F(ManagerTest, GetServiceUnknownType) {
849 KeyValueStore args;
850 Error e;
851 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
852 manager()->GetService(args, &e);
853 EXPECT_EQ(Error::kNotSupported, e.type());
854 EXPECT_EQ("service type is unsupported", e.message());
855}
856
857TEST_F(ManagerTest, GetServiceNoWifiDevice) {
858 KeyValueStore args;
859 Error e;
860 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
861 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700862 EXPECT_EQ(Error::kInvalidArguments, e.type());
863 EXPECT_EQ("no wifi devices available", e.message());
864}
865
Darin Petkovb65c2452012-02-23 15:17:06 +0100866TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700867 KeyValueStore args;
868 Error e;
869 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +0100870 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700871 manager()->RegisterDevice(mock_wifi_);
872 EXPECT_CALL(*mock_wifi_, GetService(_, _))
873 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +0100874 manager()->GetService(args, &e);
875 EXPECT_TRUE(e.IsSuccess());
876}
877
Darin Petkov33af05c2012-02-28 10:10:30 +0100878TEST_F(ManagerTest, GetServiceVPNUnknownType) {
879 KeyValueStore args;
880 Error e;
881 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
882 ServiceRefPtr service = manager()->GetService(args, &e);
883 EXPECT_EQ(Error::kNotSupported, e.type());
884 EXPECT_FALSE(service);
885}
886
Darin Petkovb65c2452012-02-23 15:17:06 +0100887TEST_F(ManagerTest, GetServiceVPN) {
888 KeyValueStore args;
889 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100890 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +0100891 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +0100892 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
893 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +0100894 ServiceRefPtr service = manager()->GetService(args, &e);
895 EXPECT_TRUE(e.IsSuccess());
896 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700897}
898
Paul Stewart22aa71b2011-09-16 12:15:11 -0700899TEST_F(ManagerTest, TechnologyOrder) {
900 Error error;
901 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
902 string(flimflam::kTypeWifi), &error);
903 ASSERT_TRUE(error.IsSuccess());
904 EXPECT_EQ(manager()->GetTechnologyOrder(),
905 string(flimflam::kTypeEthernet) + "," +
906 string(flimflam::kTypeWifi));
907
908 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
909 string(flimflam::kTypeWifi), &error);
910 ASSERT_FALSE(error.IsSuccess());
911 EXPECT_EQ(Error::kInvalidArguments, error.type());
912 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
913 string(flimflam::kTypeWifi),
914 manager()->GetTechnologyOrder());
915}
916
917TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +0000918 // TODO(quiche): Some of these tests would probably fit better in
919 // service_unittest, since the actual comparison of Services is
920 // implemented in Service. (crosbug.com/23370)
921
Paul Stewart22aa71b2011-09-16 12:15:11 -0700922 scoped_refptr<MockService> mock_service0(
923 new NiceMock<MockService>(control_interface(),
924 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800925 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700926 manager()));
927 scoped_refptr<MockService> mock_service1(
928 new NiceMock<MockService>(control_interface(),
929 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800930 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700931 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700932
933 manager()->RegisterService(mock_service0);
934 manager()->RegisterService(mock_service1);
935
936 // Services should already be sorted by UniqueName
937 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
938
939 // Asking explictly to sort services should not change anything
940 manager()->SortServices();
941 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
942
943 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +0100944 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700945 manager()->UpdateService(mock_service1);
946 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
947
948 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -0700949 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700950 manager()->UpdateService(mock_service0);
951 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
952
953 // Technology
954 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
955 .WillRepeatedly(Return(true));
956 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
957 .WillRepeatedly(Return(true));
958 // NB: Redefine default (false) return values so we don't use the default rule
959 // which makes the logs noisier
960 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
961 .WillRepeatedly(Return(false));
962 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
963 .WillRepeatedly(Return(false));
964
965 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -0800966 // Default technology ordering should favor Ethernet over WiFi.
967 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700968 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
969
970 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
971 string(flimflam::kTypeEthernet), &error);
972 EXPECT_TRUE(error.IsSuccess());
973 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
974
Gaurav Shah435de2c2011-11-17 19:01:07 -0800975 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700976 mock_service0->set_priority(1);
977 manager()->UpdateService(mock_service0);
978 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
979
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000980 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +0000981 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700982 manager()->UpdateService(mock_service1);
983 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
984
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000985 // Auto-connect.
986 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700987 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000988 mock_service1->set_auto_connect(false);
989 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700990 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
991
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000992 // Connectable.
993 mock_service1->set_connectable(true);
994 manager()->UpdateService(mock_service1);
995 mock_service0->set_connectable(false);
996 manager()->UpdateService(mock_service0);
997 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
998
999 // IsFailed.
1000 EXPECT_CALL(*mock_service0.get(), state())
1001 .WillRepeatedly(Return(Service::kStateIdle));
1002 EXPECT_CALL(*mock_service0.get(), IsFailed())
1003 .WillRepeatedly(Return(false));
1004 manager()->UpdateService(mock_service0);
1005 EXPECT_CALL(*mock_service0.get(), state())
1006 .WillRepeatedly(Return(Service::kStateFailure));
1007 EXPECT_CALL(*mock_service1.get(), IsFailed())
1008 .WillRepeatedly(Return(true));
1009 manager()->UpdateService(mock_service1);
1010 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1011
1012 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001013 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001014 .WillRepeatedly(Return(Service::kStateAssociating));
1015 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001016 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001017 manager()->UpdateService(mock_service1);
1018 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1019
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001020 // Connected.
1021 EXPECT_CALL(*mock_service0.get(), state())
1022 .WillRepeatedly(Return(Service::kStateConnected));
1023 EXPECT_CALL(*mock_service0.get(), IsConnected())
1024 .WillRepeatedly(Return(true));
1025 manager()->UpdateService(mock_service0);
1026 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1027
Paul Stewart22aa71b2011-09-16 12:15:11 -07001028 manager()->DeregisterService(mock_service0);
1029 manager()->DeregisterService(mock_service1);
1030}
1031
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001032TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001033 MockMetrics mock_metrics;
1034 manager()->set_metrics(&mock_metrics);
1035
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001036 scoped_refptr<MockService> mock_service0(
1037 new NiceMock<MockService>(control_interface(),
1038 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001039 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001040 manager()));
1041 scoped_refptr<MockService> mock_service1(
1042 new NiceMock<MockService>(control_interface(),
1043 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001044 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001045 manager()));
1046
1047 scoped_refptr<MockConnection> mock_connection0(
1048 new NiceMock<MockConnection>(device_info_.get()));
1049 scoped_refptr<MockConnection> mock_connection1(
1050 new NiceMock<MockConnection>(device_info_.get()));
1051
1052 manager()->RegisterService(mock_service0);
1053 manager()->RegisterService(mock_service1);
1054
1055 mock_service0->connection_ = mock_connection0;
1056 mock_service1->connection_ = mock_connection1;
1057
1058 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001059 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001060 manager()->SortServices();
1061
1062 mock_service1->set_priority(1);
1063 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1064 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001065 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001066 manager()->SortServices();
1067
1068 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001069 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001070 mock_service1->connection_ = NULL;
1071 manager()->DeregisterService(mock_service1);
1072
1073 mock_service0->connection_ = NULL;
1074 manager()->DeregisterService(mock_service0);
1075}
1076
Gaurav Shah435de2c2011-11-17 19:01:07 -08001077TEST_F(ManagerTest, AvailableTechnologies) {
1078 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1079 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001080 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001081 manager(),
1082 "null4",
1083 "addr4",
1084 0));
1085 manager()->RegisterDevice(mock_devices_[0]);
1086 manager()->RegisterDevice(mock_devices_[1]);
1087 manager()->RegisterDevice(mock_devices_[2]);
1088 manager()->RegisterDevice(mock_devices_[3]);
1089
1090 ON_CALL(*mock_devices_[0].get(), technology())
1091 .WillByDefault(Return(Technology::kEthernet));
1092 ON_CALL(*mock_devices_[1].get(), technology())
1093 .WillByDefault(Return(Technology::kWifi));
1094 ON_CALL(*mock_devices_[2].get(), technology())
1095 .WillByDefault(Return(Technology::kCellular));
1096 ON_CALL(*mock_devices_[3].get(), technology())
1097 .WillByDefault(Return(Technology::kWifi));
1098
1099 set<string> expected_technologies;
1100 expected_technologies.insert(Technology::NameFromIdentifier(
1101 Technology::kEthernet));
1102 expected_technologies.insert(Technology::NameFromIdentifier(
1103 Technology::kWifi));
1104 expected_technologies.insert(Technology::NameFromIdentifier(
1105 Technology::kCellular));
1106 Error error;
1107 vector<string> technologies = manager()->AvailableTechnologies(&error);
1108
1109 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1110 ContainerEq(expected_technologies));
1111}
1112
1113TEST_F(ManagerTest, ConnectedTechnologies) {
1114 scoped_refptr<MockService> connected_service1(
1115 new NiceMock<MockService>(control_interface(),
1116 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001117 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001118 manager()));
1119 scoped_refptr<MockService> connected_service2(
1120 new NiceMock<MockService>(control_interface(),
1121 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001122 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001123 manager()));
1124 scoped_refptr<MockService> disconnected_service1(
1125 new NiceMock<MockService>(control_interface(),
1126 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001127 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001128 manager()));
1129 scoped_refptr<MockService> disconnected_service2(
1130 new NiceMock<MockService>(control_interface(),
1131 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001132 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001133 manager()));
1134
1135 ON_CALL(*connected_service1.get(), IsConnected())
1136 .WillByDefault(Return(true));
1137 ON_CALL(*connected_service2.get(), IsConnected())
1138 .WillByDefault(Return(true));
1139
1140 manager()->RegisterService(connected_service1);
1141 manager()->RegisterService(connected_service2);
1142 manager()->RegisterService(disconnected_service1);
1143 manager()->RegisterService(disconnected_service2);
1144
1145 manager()->RegisterDevice(mock_devices_[0]);
1146 manager()->RegisterDevice(mock_devices_[1]);
1147 manager()->RegisterDevice(mock_devices_[2]);
1148 manager()->RegisterDevice(mock_devices_[3]);
1149
1150 ON_CALL(*mock_devices_[0].get(), technology())
1151 .WillByDefault(Return(Technology::kEthernet));
1152 ON_CALL(*mock_devices_[1].get(), technology())
1153 .WillByDefault(Return(Technology::kWifi));
1154 ON_CALL(*mock_devices_[2].get(), technology())
1155 .WillByDefault(Return(Technology::kCellular));
1156 ON_CALL(*mock_devices_[3].get(), technology())
1157 .WillByDefault(Return(Technology::kWifi));
1158
1159 mock_devices_[0]->SelectService(connected_service1);
1160 mock_devices_[1]->SelectService(disconnected_service1);
1161 mock_devices_[2]->SelectService(disconnected_service2);
1162 mock_devices_[3]->SelectService(connected_service2);
1163
1164 set<string> expected_technologies;
1165 expected_technologies.insert(Technology::NameFromIdentifier(
1166 Technology::kEthernet));
1167 expected_technologies.insert(Technology::NameFromIdentifier(
1168 Technology::kWifi));
1169 Error error;
1170
1171 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1172 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1173 ContainerEq(expected_technologies));
1174}
1175
1176TEST_F(ManagerTest, DefaultTechnology) {
1177 scoped_refptr<MockService> connected_service(
1178 new NiceMock<MockService>(control_interface(),
1179 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001180 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001181 manager()));
1182 scoped_refptr<MockService> disconnected_service(
1183 new NiceMock<MockService>(control_interface(),
1184 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001185 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001186 manager()));
1187
1188 // Connected. WiFi.
1189 ON_CALL(*connected_service.get(), IsConnected())
1190 .WillByDefault(Return(true));
1191 ON_CALL(*connected_service.get(), state())
1192 .WillByDefault(Return(Service::kStateConnected));
1193 ON_CALL(*connected_service.get(), technology())
1194 .WillByDefault(Return(Technology::kWifi));
1195
1196 // Disconnected. Ethernet.
1197 ON_CALL(*disconnected_service.get(), technology())
1198 .WillByDefault(Return(Technology::kEthernet));
1199
1200 manager()->RegisterService(disconnected_service);
1201 Error error;
1202 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1203
1204
1205 manager()->RegisterService(connected_service);
1206 // Connected service should be brought to the front now.
1207 string expected_technology =
1208 Technology::NameFromIdentifier(Technology::kWifi);
1209 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1210}
1211
Thieu Le1271d682011-11-02 22:48:19 +00001212TEST_F(ManagerTest, DisconnectServicesOnStop) {
1213 scoped_refptr<MockService> mock_service(
1214 new NiceMock<MockService>(control_interface(),
1215 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001216 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001217 manager()));
1218 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001219 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001220 manager()->Stop();
1221}
1222
mukesh agrawal00917ce2011-11-22 23:56:55 +00001223TEST_F(ManagerTest, UpdateServiceConnected) {
1224 scoped_refptr<MockService> mock_service(
1225 new NiceMock<MockService>(control_interface(),
1226 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001227 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001228 manager()));
1229 manager()->RegisterService(mock_service);
1230 EXPECT_FALSE(mock_service->favorite());
1231 EXPECT_FALSE(mock_service->auto_connect());
1232
Gaurav Shah435de2c2011-11-17 19:01:07 -08001233 EXPECT_CALL(*mock_service.get(), IsConnected())
1234 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001235 manager()->UpdateService(mock_service);
1236 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1237 // to mock out MakeFavorite. And mocking that out would break the
1238 // SortServices test. (crosbug.com/23370)
1239 EXPECT_TRUE(mock_service->favorite());
1240 EXPECT_TRUE(mock_service->auto_connect());
1241}
1242
Thieu Led4e9e552012-02-16 16:26:07 -08001243TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1244 // This tests the case where the user connects to a service that is
1245 // currently associated with a profile. We want to make sure that the
1246 // favorite flag is set and that the flag is saved to the current
1247 // profile.
1248 scoped_refptr<MockService> mock_service(
1249 new NiceMock<MockService>(control_interface(),
1250 dispatcher(),
1251 metrics(),
1252 manager()));
1253 manager()->RegisterService(mock_service);
1254 EXPECT_FALSE(mock_service->favorite());
1255 EXPECT_FALSE(mock_service->auto_connect());
1256
1257 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1258 mock_service->set_profile(profile);
1259
1260 EXPECT_CALL(*mock_service.get(), IsConnected())
1261 .WillRepeatedly(Return(true));
1262 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1263 manager()->UpdateService(mock_service);
1264 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1265 // to mock out MakeFavorite. And mocking that out would break the
1266 // SortServices test. (crosbug.com/23370)
1267 EXPECT_TRUE(mock_service->favorite());
1268 EXPECT_TRUE(mock_service->auto_connect());
1269}
1270
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001271TEST_F(ManagerTest, SaveSuccessfulService) {
1272 scoped_refptr<MockProfile> profile(
1273 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1274 AdoptProfile(manager(), profile);
1275 scoped_refptr<MockService> service(
1276 new NiceMock<MockService>(control_interface(),
1277 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001278 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001279 manager()));
1280
1281 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1282 ServiceRefPtr expect_service(service.get());
1283
1284 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1285 .WillOnce(Return(false));
1286 manager()->RegisterService(service);
1287
1288 EXPECT_CALL(*service.get(), state())
1289 .WillRepeatedly(Return(Service::kStateConnected));
1290 EXPECT_CALL(*service.get(), IsConnected())
1291 .WillRepeatedly(Return(true));
1292 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1293 .WillOnce(Return(true));
1294 manager()->UpdateService(service);
1295}
1296
Paul Stewart1b253142012-01-26 14:05:52 -08001297TEST_F(ManagerTest, EnumerateProfiles) {
1298 vector<string> profile_paths;
1299 for (size_t i = 0; i < 10; i++) {
1300 scoped_refptr<MockProfile> profile(
1301 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001302 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001303 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1304 .WillOnce(Return(profile_paths.back()));
1305 AdoptProfile(manager(), profile);
1306 }
1307
1308 Error error;
1309 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1310 EXPECT_TRUE(error.IsSuccess());
1311 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1312 for (size_t i = 0; i < profile_paths.size(); i++) {
1313 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1314 }
1315}
1316
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001317TEST_F(ManagerTest, AutoConnectOnRegister) {
1318 MockServiceRefPtr service = MakeAutoConnectableService();
1319 EXPECT_CALL(*service.get(), AutoConnect());
1320 manager()->RegisterService(service);
1321 dispatcher()->DispatchPendingEvents();
1322}
1323
1324TEST_F(ManagerTest, AutoConnectOnUpdate) {
1325 MockServiceRefPtr service1 = MakeAutoConnectableService();
1326 service1->set_priority(1);
1327 MockServiceRefPtr service2 = MakeAutoConnectableService();
1328 service2->set_priority(2);
1329 manager()->RegisterService(service1);
1330 manager()->RegisterService(service2);
1331 dispatcher()->DispatchPendingEvents();
1332
1333 EXPECT_CALL(*service1.get(), AutoConnect());
1334 EXPECT_CALL(*service2.get(), state())
1335 .WillRepeatedly(Return(Service::kStateFailure));
1336 EXPECT_CALL(*service2.get(), IsFailed())
1337 .WillRepeatedly(Return(true));
1338 EXPECT_CALL(*service2.get(), IsConnected())
1339 .WillRepeatedly(Return(false));
1340 manager()->UpdateService(service2);
1341 dispatcher()->DispatchPendingEvents();
1342}
1343
1344TEST_F(ManagerTest, AutoConnectOnDeregister) {
1345 MockServiceRefPtr service1 = MakeAutoConnectableService();
1346 service1->set_priority(1);
1347 MockServiceRefPtr service2 = MakeAutoConnectableService();
1348 service2->set_priority(2);
1349 manager()->RegisterService(service1);
1350 manager()->RegisterService(service2);
1351 dispatcher()->DispatchPendingEvents();
1352
1353 EXPECT_CALL(*service1.get(), AutoConnect());
1354 manager()->DeregisterService(service2);
1355 dispatcher()->DispatchPendingEvents();
1356}
1357
Paul Stewartc681fa02012-03-02 19:40:04 -08001358TEST_F(ManagerTest, RecheckPortal) {
1359 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1360 .WillOnce(Return(false));
1361 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1362 .WillOnce(Return(true));
1363 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1364 .Times(0);
1365
1366 manager()->RegisterDevice(mock_devices_[0]);
1367 manager()->RegisterDevice(mock_devices_[1]);
1368 manager()->RegisterDevice(mock_devices_[2]);
1369
1370 manager()->RecheckPortal(NULL);
1371}
1372
Chris Masone9be4a9d2011-05-16 15:44:09 -07001373} // namespace shill