blob: ec739a298637f86c7651f0ce016121e00e423442 [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
878TEST_F(ManagerTest, GetServiceVPN) {
879 KeyValueStore args;
880 Error e;
881 WiFiServiceRefPtr wifi_service;
882 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
883 manager()->GetService(args, &e);
884 // TODO(petkov): Test that a VPN service is created.
885 EXPECT_EQ(Error::kNotSupported, e.type());
886 EXPECT_EQ("service type is unsupported", e.message());
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700887}
888
Paul Stewart22aa71b2011-09-16 12:15:11 -0700889TEST_F(ManagerTest, TechnologyOrder) {
890 Error error;
891 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
892 string(flimflam::kTypeWifi), &error);
893 ASSERT_TRUE(error.IsSuccess());
894 EXPECT_EQ(manager()->GetTechnologyOrder(),
895 string(flimflam::kTypeEthernet) + "," +
896 string(flimflam::kTypeWifi));
897
898 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
899 string(flimflam::kTypeWifi), &error);
900 ASSERT_FALSE(error.IsSuccess());
901 EXPECT_EQ(Error::kInvalidArguments, error.type());
902 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
903 string(flimflam::kTypeWifi),
904 manager()->GetTechnologyOrder());
905}
906
907TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +0000908 // TODO(quiche): Some of these tests would probably fit better in
909 // service_unittest, since the actual comparison of Services is
910 // implemented in Service. (crosbug.com/23370)
911
Paul Stewart22aa71b2011-09-16 12:15:11 -0700912 scoped_refptr<MockService> mock_service0(
913 new NiceMock<MockService>(control_interface(),
914 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800915 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700916 manager()));
917 scoped_refptr<MockService> mock_service1(
918 new NiceMock<MockService>(control_interface(),
919 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800920 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700921 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700922
923 manager()->RegisterService(mock_service0);
924 manager()->RegisterService(mock_service1);
925
926 // Services should already be sorted by UniqueName
927 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
928
929 // Asking explictly to sort services should not change anything
930 manager()->SortServices();
931 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
932
933 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +0100934 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700935 manager()->UpdateService(mock_service1);
936 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
937
938 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -0700939 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700940 manager()->UpdateService(mock_service0);
941 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
942
943 // Technology
944 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
945 .WillRepeatedly(Return(true));
946 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
947 .WillRepeatedly(Return(true));
948 // NB: Redefine default (false) return values so we don't use the default rule
949 // which makes the logs noisier
950 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
951 .WillRepeatedly(Return(false));
952 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
953 .WillRepeatedly(Return(false));
954
955 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -0800956 // Default technology ordering should favor Ethernet over WiFi.
957 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700958 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
959
960 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
961 string(flimflam::kTypeEthernet), &error);
962 EXPECT_TRUE(error.IsSuccess());
963 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
964
Gaurav Shah435de2c2011-11-17 19:01:07 -0800965 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700966 mock_service0->set_priority(1);
967 manager()->UpdateService(mock_service0);
968 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
969
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000970 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +0000971 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700972 manager()->UpdateService(mock_service1);
973 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
974
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000975 // Auto-connect.
976 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700977 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000978 mock_service1->set_auto_connect(false);
979 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700980 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
981
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000982 // Connectable.
983 mock_service1->set_connectable(true);
984 manager()->UpdateService(mock_service1);
985 mock_service0->set_connectable(false);
986 manager()->UpdateService(mock_service0);
987 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
988
989 // IsFailed.
990 EXPECT_CALL(*mock_service0.get(), state())
991 .WillRepeatedly(Return(Service::kStateIdle));
992 EXPECT_CALL(*mock_service0.get(), IsFailed())
993 .WillRepeatedly(Return(false));
994 manager()->UpdateService(mock_service0);
995 EXPECT_CALL(*mock_service0.get(), state())
996 .WillRepeatedly(Return(Service::kStateFailure));
997 EXPECT_CALL(*mock_service1.get(), IsFailed())
998 .WillRepeatedly(Return(true));
999 manager()->UpdateService(mock_service1);
1000 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1001
1002 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001003 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001004 .WillRepeatedly(Return(Service::kStateAssociating));
1005 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001006 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001007 manager()->UpdateService(mock_service1);
1008 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1009
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001010 // Connected.
1011 EXPECT_CALL(*mock_service0.get(), state())
1012 .WillRepeatedly(Return(Service::kStateConnected));
1013 EXPECT_CALL(*mock_service0.get(), IsConnected())
1014 .WillRepeatedly(Return(true));
1015 manager()->UpdateService(mock_service0);
1016 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1017
Paul Stewart22aa71b2011-09-16 12:15:11 -07001018 manager()->DeregisterService(mock_service0);
1019 manager()->DeregisterService(mock_service1);
1020}
1021
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001022TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001023 MockMetrics mock_metrics;
1024 manager()->set_metrics(&mock_metrics);
1025
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001026 scoped_refptr<MockService> mock_service0(
1027 new NiceMock<MockService>(control_interface(),
1028 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001029 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001030 manager()));
1031 scoped_refptr<MockService> mock_service1(
1032 new NiceMock<MockService>(control_interface(),
1033 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001034 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001035 manager()));
1036
1037 scoped_refptr<MockConnection> mock_connection0(
1038 new NiceMock<MockConnection>(device_info_.get()));
1039 scoped_refptr<MockConnection> mock_connection1(
1040 new NiceMock<MockConnection>(device_info_.get()));
1041
1042 manager()->RegisterService(mock_service0);
1043 manager()->RegisterService(mock_service1);
1044
1045 mock_service0->connection_ = mock_connection0;
1046 mock_service1->connection_ = mock_connection1;
1047
1048 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001049 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001050 manager()->SortServices();
1051
1052 mock_service1->set_priority(1);
1053 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1054 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001055 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001056 manager()->SortServices();
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 mock_service1->connection_ = NULL;
1061 manager()->DeregisterService(mock_service1);
1062
1063 mock_service0->connection_ = NULL;
1064 manager()->DeregisterService(mock_service0);
1065}
1066
Gaurav Shah435de2c2011-11-17 19:01:07 -08001067TEST_F(ManagerTest, AvailableTechnologies) {
1068 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1069 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001070 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001071 manager(),
1072 "null4",
1073 "addr4",
1074 0));
1075 manager()->RegisterDevice(mock_devices_[0]);
1076 manager()->RegisterDevice(mock_devices_[1]);
1077 manager()->RegisterDevice(mock_devices_[2]);
1078 manager()->RegisterDevice(mock_devices_[3]);
1079
1080 ON_CALL(*mock_devices_[0].get(), technology())
1081 .WillByDefault(Return(Technology::kEthernet));
1082 ON_CALL(*mock_devices_[1].get(), technology())
1083 .WillByDefault(Return(Technology::kWifi));
1084 ON_CALL(*mock_devices_[2].get(), technology())
1085 .WillByDefault(Return(Technology::kCellular));
1086 ON_CALL(*mock_devices_[3].get(), technology())
1087 .WillByDefault(Return(Technology::kWifi));
1088
1089 set<string> expected_technologies;
1090 expected_technologies.insert(Technology::NameFromIdentifier(
1091 Technology::kEthernet));
1092 expected_technologies.insert(Technology::NameFromIdentifier(
1093 Technology::kWifi));
1094 expected_technologies.insert(Technology::NameFromIdentifier(
1095 Technology::kCellular));
1096 Error error;
1097 vector<string> technologies = manager()->AvailableTechnologies(&error);
1098
1099 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1100 ContainerEq(expected_technologies));
1101}
1102
1103TEST_F(ManagerTest, ConnectedTechnologies) {
1104 scoped_refptr<MockService> connected_service1(
1105 new NiceMock<MockService>(control_interface(),
1106 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001107 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001108 manager()));
1109 scoped_refptr<MockService> connected_service2(
1110 new NiceMock<MockService>(control_interface(),
1111 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001112 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001113 manager()));
1114 scoped_refptr<MockService> disconnected_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> disconnected_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
1125 ON_CALL(*connected_service1.get(), IsConnected())
1126 .WillByDefault(Return(true));
1127 ON_CALL(*connected_service2.get(), IsConnected())
1128 .WillByDefault(Return(true));
1129
1130 manager()->RegisterService(connected_service1);
1131 manager()->RegisterService(connected_service2);
1132 manager()->RegisterService(disconnected_service1);
1133 manager()->RegisterService(disconnected_service2);
1134
1135 manager()->RegisterDevice(mock_devices_[0]);
1136 manager()->RegisterDevice(mock_devices_[1]);
1137 manager()->RegisterDevice(mock_devices_[2]);
1138 manager()->RegisterDevice(mock_devices_[3]);
1139
1140 ON_CALL(*mock_devices_[0].get(), technology())
1141 .WillByDefault(Return(Technology::kEthernet));
1142 ON_CALL(*mock_devices_[1].get(), technology())
1143 .WillByDefault(Return(Technology::kWifi));
1144 ON_CALL(*mock_devices_[2].get(), technology())
1145 .WillByDefault(Return(Technology::kCellular));
1146 ON_CALL(*mock_devices_[3].get(), technology())
1147 .WillByDefault(Return(Technology::kWifi));
1148
1149 mock_devices_[0]->SelectService(connected_service1);
1150 mock_devices_[1]->SelectService(disconnected_service1);
1151 mock_devices_[2]->SelectService(disconnected_service2);
1152 mock_devices_[3]->SelectService(connected_service2);
1153
1154 set<string> expected_technologies;
1155 expected_technologies.insert(Technology::NameFromIdentifier(
1156 Technology::kEthernet));
1157 expected_technologies.insert(Technology::NameFromIdentifier(
1158 Technology::kWifi));
1159 Error error;
1160
1161 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1162 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1163 ContainerEq(expected_technologies));
1164}
1165
1166TEST_F(ManagerTest, DefaultTechnology) {
1167 scoped_refptr<MockService> connected_service(
1168 new NiceMock<MockService>(control_interface(),
1169 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001170 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001171 manager()));
1172 scoped_refptr<MockService> disconnected_service(
1173 new NiceMock<MockService>(control_interface(),
1174 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001175 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001176 manager()));
1177
1178 // Connected. WiFi.
1179 ON_CALL(*connected_service.get(), IsConnected())
1180 .WillByDefault(Return(true));
1181 ON_CALL(*connected_service.get(), state())
1182 .WillByDefault(Return(Service::kStateConnected));
1183 ON_CALL(*connected_service.get(), technology())
1184 .WillByDefault(Return(Technology::kWifi));
1185
1186 // Disconnected. Ethernet.
1187 ON_CALL(*disconnected_service.get(), technology())
1188 .WillByDefault(Return(Technology::kEthernet));
1189
1190 manager()->RegisterService(disconnected_service);
1191 Error error;
1192 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1193
1194
1195 manager()->RegisterService(connected_service);
1196 // Connected service should be brought to the front now.
1197 string expected_technology =
1198 Technology::NameFromIdentifier(Technology::kWifi);
1199 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1200}
1201
Thieu Le1271d682011-11-02 22:48:19 +00001202TEST_F(ManagerTest, DisconnectServicesOnStop) {
1203 scoped_refptr<MockService> mock_service(
1204 new NiceMock<MockService>(control_interface(),
1205 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001206 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001207 manager()));
1208 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001209 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001210 manager()->Stop();
1211}
1212
mukesh agrawal00917ce2011-11-22 23:56:55 +00001213TEST_F(ManagerTest, UpdateServiceConnected) {
1214 scoped_refptr<MockService> mock_service(
1215 new NiceMock<MockService>(control_interface(),
1216 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001217 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001218 manager()));
1219 manager()->RegisterService(mock_service);
1220 EXPECT_FALSE(mock_service->favorite());
1221 EXPECT_FALSE(mock_service->auto_connect());
1222
Gaurav Shah435de2c2011-11-17 19:01:07 -08001223 EXPECT_CALL(*mock_service.get(), IsConnected())
1224 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001225 manager()->UpdateService(mock_service);
1226 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1227 // to mock out MakeFavorite. And mocking that out would break the
1228 // SortServices test. (crosbug.com/23370)
1229 EXPECT_TRUE(mock_service->favorite());
1230 EXPECT_TRUE(mock_service->auto_connect());
1231}
1232
Thieu Led4e9e552012-02-16 16:26:07 -08001233TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1234 // This tests the case where the user connects to a service that is
1235 // currently associated with a profile. We want to make sure that the
1236 // favorite flag is set and that the flag is saved to the current
1237 // profile.
1238 scoped_refptr<MockService> mock_service(
1239 new NiceMock<MockService>(control_interface(),
1240 dispatcher(),
1241 metrics(),
1242 manager()));
1243 manager()->RegisterService(mock_service);
1244 EXPECT_FALSE(mock_service->favorite());
1245 EXPECT_FALSE(mock_service->auto_connect());
1246
1247 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1248 mock_service->set_profile(profile);
1249
1250 EXPECT_CALL(*mock_service.get(), IsConnected())
1251 .WillRepeatedly(Return(true));
1252 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1253 manager()->UpdateService(mock_service);
1254 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1255 // to mock out MakeFavorite. And mocking that out would break the
1256 // SortServices test. (crosbug.com/23370)
1257 EXPECT_TRUE(mock_service->favorite());
1258 EXPECT_TRUE(mock_service->auto_connect());
1259}
1260
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001261TEST_F(ManagerTest, SaveSuccessfulService) {
1262 scoped_refptr<MockProfile> profile(
1263 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1264 AdoptProfile(manager(), profile);
1265 scoped_refptr<MockService> service(
1266 new NiceMock<MockService>(control_interface(),
1267 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001268 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001269 manager()));
1270
1271 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1272 ServiceRefPtr expect_service(service.get());
1273
1274 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1275 .WillOnce(Return(false));
1276 manager()->RegisterService(service);
1277
1278 EXPECT_CALL(*service.get(), state())
1279 .WillRepeatedly(Return(Service::kStateConnected));
1280 EXPECT_CALL(*service.get(), IsConnected())
1281 .WillRepeatedly(Return(true));
1282 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1283 .WillOnce(Return(true));
1284 manager()->UpdateService(service);
1285}
1286
Paul Stewart1b253142012-01-26 14:05:52 -08001287TEST_F(ManagerTest, EnumerateProfiles) {
1288 vector<string> profile_paths;
1289 for (size_t i = 0; i < 10; i++) {
1290 scoped_refptr<MockProfile> profile(
1291 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001292 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001293 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1294 .WillOnce(Return(profile_paths.back()));
1295 AdoptProfile(manager(), profile);
1296 }
1297
1298 Error error;
1299 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1300 EXPECT_TRUE(error.IsSuccess());
1301 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1302 for (size_t i = 0; i < profile_paths.size(); i++) {
1303 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1304 }
1305}
1306
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001307TEST_F(ManagerTest, AutoConnectOnRegister) {
1308 MockServiceRefPtr service = MakeAutoConnectableService();
1309 EXPECT_CALL(*service.get(), AutoConnect());
1310 manager()->RegisterService(service);
1311 dispatcher()->DispatchPendingEvents();
1312}
1313
1314TEST_F(ManagerTest, AutoConnectOnUpdate) {
1315 MockServiceRefPtr service1 = MakeAutoConnectableService();
1316 service1->set_priority(1);
1317 MockServiceRefPtr service2 = MakeAutoConnectableService();
1318 service2->set_priority(2);
1319 manager()->RegisterService(service1);
1320 manager()->RegisterService(service2);
1321 dispatcher()->DispatchPendingEvents();
1322
1323 EXPECT_CALL(*service1.get(), AutoConnect());
1324 EXPECT_CALL(*service2.get(), state())
1325 .WillRepeatedly(Return(Service::kStateFailure));
1326 EXPECT_CALL(*service2.get(), IsFailed())
1327 .WillRepeatedly(Return(true));
1328 EXPECT_CALL(*service2.get(), IsConnected())
1329 .WillRepeatedly(Return(false));
1330 manager()->UpdateService(service2);
1331 dispatcher()->DispatchPendingEvents();
1332}
1333
1334TEST_F(ManagerTest, AutoConnectOnDeregister) {
1335 MockServiceRefPtr service1 = MakeAutoConnectableService();
1336 service1->set_priority(1);
1337 MockServiceRefPtr service2 = MakeAutoConnectableService();
1338 service2->set_priority(2);
1339 manager()->RegisterService(service1);
1340 manager()->RegisterService(service2);
1341 dispatcher()->DispatchPendingEvents();
1342
1343 EXPECT_CALL(*service1.get(), AutoConnect());
1344 manager()->DeregisterService(service2);
1345 dispatcher()->DispatchPendingEvents();
1346}
1347
Chris Masone9be4a9d2011-05-16 15:44:09 -07001348} // namespace shill