blob: 2e73f5a6a1174f621973d6158d4e2b68d412d27a [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
Jason Glasgowdf7c5532012-05-14 14:41:45 -04007#include <map>
Chris Masone6791a432011-07-12 13:23:19 -07008#include <set>
9
Chris Masone9be4a9d2011-05-16 15:44:09 -070010#include <glib.h>
11
Paul Stewarte73d05c2012-03-29 16:26:05 -070012#include <base/file_util.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050013#include <base/scoped_temp_dir.h>
14#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070015#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070017#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070018#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070019
mukesh agrawal32399322011-09-01 10:53:43 -070020#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070021#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070022#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070023#include "shill/glib.h"
24#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070025#include "shill/key_value_store.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070026#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070027#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080028#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070029#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070030#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080031#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070032#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000033#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020034#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070035#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070036#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070037#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070038#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070039#include "shill/mock_wifi.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070040#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070041#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020042#include "shill/proxy_factory.h"
Chris Masone6515aab2011-10-12 16:19:09 -070043#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070044#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020045#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070046
47using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070048using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070049using std::string;
50using std::vector;
51
Chris Masone9be4a9d2011-05-16 15:44:09 -070052namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070053using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070054using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080055using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070056using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070057using ::testing::InSequence;
mukesh agrawal784566d2012-08-08 18:32:58 -070058using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070059using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070060using ::testing::NiceMock;
61using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070062using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070063using ::testing::SaveArg;
Gaurav Shah435de2c2011-11-17 19:01:07 -080064using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080065using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070066using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070067
Chris Masone3bd3c8c2011-06-13 08:20:26 -070068class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070069 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070070 ManagerTest()
Darin Petkovca621542012-07-25 14:25:56 +020071 : power_manager_(new MockPowerManager(&proxy_factory_)),
72 mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070073 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080074 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070075 manager(),
76 "wifi0",
77 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080078 4)),
79 device_info_(new NiceMock<MockDeviceInfo>(
80 control_interface(),
81 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080082 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080083 reinterpret_cast<Manager*>(NULL))),
84 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070085 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
86 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080087 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070088 manager(),
89 "null0",
90 "addr0",
91 0));
92 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
93 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080094 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070095 manager(),
96 "null1",
97 "addr1",
98 1));
99 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
100 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800101 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700102 manager(),
103 "null2",
104 "addr2",
105 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800106 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
107 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800108 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800109 manager(),
110 "null3",
111 "addr3",
112 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700113 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800114
115 // Replace the manager's adaptor with a quieter one, and one
116 // we can do EXPECT*() against. Passes ownership.
117 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700118 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700119 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700120
Paul Stewartfdd16072011-09-16 12:41:35 -0700121 bool IsDeviceRegistered(const DeviceRefPtr &device,
122 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700123 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700124 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700125 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700126 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700127 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700128
Paul Stewarta849a3d2011-11-03 05:54:09 -0700129 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
130 manager->profiles_.push_back(profile);
131 }
132
Paul Stewart75225512012-01-26 22:51:33 -0800133 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
134 return manager->ephemeral_profile_;
135 }
136
Chris Masone6515aab2011-10-12 16:19:09 -0700137 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
138 Profile::Identifier id("rather", "irrelevant");
139 scoped_ptr<Profile> profile(new Profile(control_interface(),
140 manager,
141 id,
142 "",
143 false));
144 FilePath final_path(storage_path());
145 final_path = final_path.Append("test.profile");
146 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
147 storage->set_path(final_path);
148 if (!storage->Open())
149 return NULL;
150 profile->set_storage(storage.release()); // Passes ownership.
151 return profile.release();
152 }
153
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700154 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
155 const string &profile_identifier,
156 const string &service_name) {
157 GLib glib;
158 KeyFileStore store(&glib);
159 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
160 return store.Open() &&
161 store.SetString(service_name, "rather", "irrelevant") &&
162 store.Close();
163 }
164
165 Error::Type TestCreateProfile(Manager *manager, const string &name) {
166 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800167 string path;
168 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700169 return error.type();
170 }
171
172 Error::Type TestPopAnyProfile(Manager *manager) {
173 Error error;
174 manager->PopAnyProfile(&error);
175 return error.type();
176 }
177
178 Error::Type TestPopProfile(Manager *manager, const string &name) {
179 Error error;
180 manager->PopProfile(name, &error);
181 return error.type();
182 }
183
184 Error::Type TestPushProfile(Manager *manager, const string &name) {
185 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800186 string path;
187 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700188 return error.type();
189 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000190
Paul Stewartcb3eb892012-06-07 14:24:46 -0700191 void AddMockProfileToManager(Manager *manager) {
192 scoped_refptr<MockProfile> profile(
193 new MockProfile(control_interface(), manager, ""));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200194 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return("/"));
195 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700196 AdoptProfile(manager, profile);
197 }
198
Paul Stewartdfa46052012-06-26 09:44:14 -0700199 void CompleteServiceSort() {
200 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
201 dispatcher()->DispatchPendingEvents();
202 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
203 }
204
Paul Stewart49739c02012-08-08 17:24:03 -0700205 RpcIdentifier GetDefaultServiceRpcIdentifier() {
206 return manager()->GetDefaultServiceRpcIdentifier(NULL);
207 }
208
Paul Stewart4d5efb72012-09-17 12:24:34 -0700209 void SetResolver(Resolver *resolver) {
210 manager()->resolver_ = resolver;
211 }
212
213 void SetIgnoredDNSSearchPaths(const string &search_paths) {
214 manager()->SetIgnoredDNSSearchPaths(search_paths, NULL);
215 }
216
217 const string &GetIgnoredDNSSearchPaths() {
218 return manager()->props_.ignored_dns_search_paths;
219 }
220
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700221 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000222 typedef scoped_refptr<MockService> MockServiceRefPtr;
223
Darin Petkova5e07ef2012-07-09 14:27:57 +0200224 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
225 public:
226 ServiceWatcher() {}
227 virtual ~ServiceWatcher() {}
228
229 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
230
231 private:
232 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
233 };
234
Darin Petkovca621542012-07-25 14:25:56 +0200235 class TestProxyFactory : public ProxyFactory {
236 public:
237 TestProxyFactory() {}
238
239 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
240 PowerManagerProxyDelegate */*delegate*/) {
241 return NULL;
242 }
243
244 private:
245 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
246 };
247
248 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
249 power_manager_->power_state_ = state;
250 }
251
252 void SetPowerManager() {
253 manager()->set_power_manager(power_manager_.release());
254 }
255
256 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
257 manager()->OnPowerStateChanged(state);
258 }
259
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000260 MockServiceRefPtr MakeAutoConnectableService() {
261 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
262 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800263 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000264 manager());
265 service->MakeFavorite();
266 service->set_connectable(true);
267 return service;
268 }
269
Darin Petkovca621542012-07-25 14:25:56 +0200270 TestProxyFactory proxy_factory_;
271 scoped_ptr<MockPowerManager> power_manager_;
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700272 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700273 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800274 scoped_ptr<MockDeviceInfo> device_info_;
275
276 // This pointer is owned by the manager, and only tracked here for EXPECT*()
277 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700278};
279
Paul Stewart22aa71b2011-09-16 12:15:11 -0700280bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700281 if (!manager()->sort_services_task_.IsCancelled()) {
282 manager()->SortServicesTask();
283 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700284 return (svc0.get() == manager()->services_[0].get() &&
285 svc1.get() == manager()->services_[1].get());
286}
287
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700288TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700289 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
290 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700291}
292
Chris Masone9be4a9d2011-05-16 15:44:09 -0700293TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700294 ON_CALL(*mock_devices_[0].get(), technology())
295 .WillByDefault(Return(Technology::kEthernet));
296 ON_CALL(*mock_devices_[1].get(), technology())
297 .WillByDefault(Return(Technology::kWifi));
298 ON_CALL(*mock_devices_[2].get(), technology())
299 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700300
Paul Stewart22aa71b2011-09-16 12:15:11 -0700301 manager()->RegisterDevice(mock_devices_[0]);
302 manager()->RegisterDevice(mock_devices_[1]);
303 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700304
Paul Stewart22aa71b2011-09-16 12:15:11 -0700305 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
306 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
307 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700308}
309
Paul Stewarta41e38d2011-11-11 07:47:29 -0800310TEST_F(ManagerTest, DeviceRegistrationAndStart) {
311 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500312 mock_devices_[0]->enabled_persistent_ = true;
313 mock_devices_[1]->enabled_persistent_ = false;
314 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800315 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500316 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800317 .Times(0);
318 manager()->RegisterDevice(mock_devices_[0]);
319 manager()->RegisterDevice(mock_devices_[1]);
320}
321
322TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
323 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
324 DeviceRefPtr device_ref(mock_devices_[0].get());
325 AdoptProfile(manager(), profile); // Passes ownership.
326 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200327 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800328 manager()->RegisterDevice(mock_devices_[0]);
329}
330
Chris Masone9be4a9d2011-05-16 15:44:09 -0700331TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700332 ON_CALL(*mock_devices_[0].get(), technology())
333 .WillByDefault(Return(Technology::kEthernet));
334 ON_CALL(*mock_devices_[1].get(), technology())
335 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700336
Gaurav Shah435de2c2011-11-17 19:01:07 -0800337 manager()->RegisterDevice(mock_devices_[0]);
338 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700339
Paul Stewart22aa71b2011-09-16 12:15:11 -0700340 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
341 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700342
Paul Stewart212d60f2012-07-12 10:59:13 -0700343 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
344 AdoptProfile(manager(), profile); // Passes ownership.
345
Eric Shienbrood9a245532012-03-07 14:20:39 -0500346 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700347 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800348 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700349 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700350
Eric Shienbrood9a245532012-03-07 14:20:39 -0500351 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700352 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800353 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700354 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700355}
356
357TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700358 // It's much easier and safer to use a real GLib for this test.
359 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700360 Manager manager(control_interface(),
361 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800362 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700363 &glib,
364 run_path(),
365 storage_path(),
366 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700367 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
368 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700369 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700370
Chris Masone9be4a9d2011-05-16 15:44:09 -0700371 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700372 new NiceMock<MockService>(control_interface(),
373 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800374 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700375 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700376 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700377 new NiceMock<MockService>(control_interface(),
378 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700380 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700381
mukesh agrawal51a7e932011-07-27 16:18:26 -0700382 string service1_name(mock_service->UniqueName());
383 string service2_name(mock_service2->UniqueName());
384
385 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
386 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700387 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700388 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700389 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700390 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700391 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700392
Chris Masone9d779932011-08-25 16:33:41 -0700393 manager.RegisterService(mock_service);
394 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700395
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800396 Error error;
397 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700398 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700399 EXPECT_EQ(2, ids.size());
400 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
401 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700402
Chris Masone9d779932011-08-25 16:33:41 -0700403 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
404 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
405
406 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700407}
408
Chris Masone6515aab2011-10-12 16:19:09 -0700409TEST_F(ManagerTest, RegisterKnownService) {
410 // It's much easier and safer to use a real GLib for this test.
411 GLib glib;
412 Manager manager(control_interface(),
413 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800414 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700415 &glib,
416 run_path(),
417 storage_path(),
418 string());
419 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
420 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700421 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700422 {
423 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
424 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800425 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700426 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700427 ASSERT_TRUE(profile->AdoptService(service1));
428 ASSERT_TRUE(profile->ContainsService(service1));
429 } // Force destruction of service1.
430
431 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
432 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800433 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700434 &manager));
435 manager.RegisterService(service2);
436 EXPECT_EQ(service2->profile().get(), profile.get());
437 manager.Stop();
438}
439
440TEST_F(ManagerTest, RegisterUnknownService) {
441 // It's much easier and safer to use a real GLib for this test.
442 GLib glib;
443 Manager manager(control_interface(),
444 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800445 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700446 &glib,
447 run_path(),
448 storage_path(),
449 string());
450 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
451 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700452 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700453 {
454 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
455 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800456 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700457 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700458 ASSERT_TRUE(profile->AdoptService(service1));
459 ASSERT_TRUE(profile->ContainsService(service1));
460 } // Force destruction of service1.
461 scoped_refptr<MockService> mock_service2(
462 new NiceMock<MockService>(control_interface(),
463 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800464 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700465 &manager));
466 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
467 .WillRepeatedly(Return(mock_service2->UniqueName()));
468 manager.RegisterService(mock_service2);
469 EXPECT_NE(mock_service2->profile().get(), profile.get());
470 manager.Stop();
471}
472
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000473TEST_F(ManagerTest, DeregisterUnregisteredService) {
474 // WiFi assumes that it can deregister a service that is not
475 // registered. (E.g. a hidden service can be deregistered when it
476 // loses its last endpoint, and again when WiFi is Stop()-ed.)
477 //
478 // So test that doing so doesn't cause a crash.
479 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
480 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800481 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000482 manager());
483 manager()->DeregisterService(service);
484}
485
Chris Masonea8a2c252011-06-27 22:16:30 -0700486TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700487 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700488 map<string, ::DBus::Variant> props;
489 Error error(Error::kInvalidProperty, "");
490 {
491 ::DBus::Error dbus_error;
492 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700493 manager()->mutable_store()->SetStringProperty(
494 flimflam::kCheckPortalListProperty,
495 expected,
496 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700497 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700498 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
499 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
500 expected);
501 }
502 {
503 ::DBus::Error dbus_error;
504 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700505 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
506 expected,
507 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700508 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700509 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
510 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
511 expected);
512 }
513}
514
Chris Masone3c3f6a12011-07-01 10:01:41 -0700515TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700516 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800517 manager()->RegisterDevice(mock_devices_[0]);
518 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700519 {
520 map<string, ::DBus::Variant> props;
521 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700522 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700523 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700524 vector < ::DBus::Path> devices =
525 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700526 EXPECT_EQ(2, devices.size());
527 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700528}
529
mukesh agrawal2366eed2012-03-20 18:21:50 -0700530TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700531 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700532 map<string, ::DBus::Variant> props;
533 ::DBus::Error dbus_error;
534 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
535 map<string, ::DBus::Variant>::const_iterator prop =
536 props.find(flimflam::kServicesProperty);
537 ASSERT_FALSE(prop == props.end());
538 const ::DBus::Variant &variant = prop->second;
539 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
540}
541
Chris Masone6791a432011-07-12 13:23:19 -0700542TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700543 Manager manager(control_interface(),
544 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800545 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700546 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700547 run_path(),
548 storage_path(),
549 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700550 scoped_refptr<MockService> s2(new MockService(control_interface(),
551 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800552 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700553 &manager));
554 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700555 {
Chris Masone6515aab2011-10-12 16:19:09 -0700556 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700557 ProfileRefPtr profile(
558 new Profile(control_interface(), &manager, id, "", false));
559 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700560 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700561 .WillRepeatedly(Return(true));
562 EXPECT_CALL(*storage, Flush())
563 .Times(AnyNumber())
564 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700565 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700566 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700567 }
Chris Masone6515aab2011-10-12 16:19:09 -0700568 // Create a profile that already has |s2| in it.
569 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700570 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700571
Chris Masone6515aab2011-10-12 16:19:09 -0700572 // Now, move the Service |s2| to another profile.
573 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
574 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700575
576 // Force destruction of the original Profile, to ensure that the Service
577 // is kept alive and populated with data.
578 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700579 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700580 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700581}
582
Paul Stewart7f61e522012-03-22 11:13:45 -0700583TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
584 scoped_refptr<MockProfile> mock_profile(
585 new MockProfile(control_interface(), manager(), ""));
586 const string kProfileName("profile0");
587 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
588 .WillRepeatedly(Return(kProfileName));
589 AdoptProfile(manager(), mock_profile);
590
591 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
592 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
593 EXPECT_EQ(mock_profile.get(), profile.get());
594}
595
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800596TEST_F(ManagerTest, SetProfileForService) {
597 scoped_refptr<MockProfile> profile0(
598 new MockProfile(control_interface(), manager(), ""));
599 string profile_name0("profile0");
600 EXPECT_CALL(*profile0, GetRpcIdentifier())
601 .WillRepeatedly(Return(profile_name0));
602 AdoptProfile(manager(), profile0);
603 scoped_refptr<MockService> service(new MockService(control_interface(),
604 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800605 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800606 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700607 EXPECT_FALSE(manager()->HasService(service));
608 {
609 Error error;
610 EXPECT_CALL(*profile0, AdoptService(_))
611 .WillOnce(Return(true));
612 // Expect that setting the profile of a service that does not already
613 // have one assigned does not cause a crash.
614 manager()->SetProfileForService(service, "profile0", &error);
615 EXPECT_TRUE(error.IsSuccess());
616 }
617
618 // The service should be registered as a side-effect of the profile being
619 // set for this service.
620 EXPECT_TRUE(manager()->HasService(service));
621
622 // Since we have mocked Profile::AdoptServie() above, the service's
623 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800624 service->set_profile(profile0);
625
626 {
627 Error error;
628 manager()->SetProfileForService(service, "foo", &error);
629 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700630 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800631 }
632
633 {
634 Error error;
635 manager()->SetProfileForService(service, profile_name0, &error);
636 EXPECT_EQ(Error::kInvalidArguments, error.type());
637 EXPECT_EQ("Service is already connected to this profile", error.message());
638 }
639
640 scoped_refptr<MockProfile> profile1(
641 new MockProfile(control_interface(), manager(), ""));
642 string profile_name1("profile1");
643 EXPECT_CALL(*profile1, GetRpcIdentifier())
644 .WillRepeatedly(Return(profile_name1));
645 AdoptProfile(manager(), profile1);
646
647 {
648 Error error;
649 EXPECT_CALL(*profile1, AdoptService(_))
650 .WillOnce(Return(true));
651 EXPECT_CALL(*profile0, AbandonService(_))
652 .WillOnce(Return(true));
653 manager()->SetProfileForService(service, profile_name1, &error);
654 EXPECT_TRUE(error.IsSuccess());
655 }
656}
657
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700658TEST_F(ManagerTest, CreateProfile) {
659 // It's much easier to use real Glib here since we want the storage
660 // side-effects.
661 GLib glib;
662 ScopedTempDir temp_dir;
663 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
664
665 Manager manager(control_interface(),
666 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800667 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700668 &glib,
669 run_path(),
670 storage_path(),
671 temp_dir.path().value());
672
673 // Invalid name should be rejected.
674 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
675
Paul Stewartd0a3b812012-03-28 22:48:22 -0700676 // A profile with invalid characters in it should similarly be rejected.
677 EXPECT_EQ(Error::kInvalidArguments,
678 TestCreateProfile(&manager, "valid_profile"));
679
680 // We should be able to create a machine profile.
681 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700682
Gary Morainb672d352012-04-25 09:19:06 -0700683 // We should succeed in creating a valid user profile. Verify the returned
684 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700685 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700686 {
687 Error error;
688 string path;
689 manager.CreateProfile(kProfile, &path, &error);
690 EXPECT_EQ(Error::kSuccess, error.type());
691 EXPECT_EQ("/profile_rpc", path);
692 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700693
694 // We should fail in creating it a second time (already exists).
695 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
696}
697
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700698// We receive PopProfile when a user logs out, and it should always trigger a
699// MemoryLog Clear() call.
700TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
701 GLib glib;
702 ScopedTempDir temp_dir;
703 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
704 Manager manager(control_interface(),
705 dispatcher(),
706 metrics(),
707 &glib,
708 run_path(),
709 storage_path(),
710 temp_dir.path().value());
711 const char kProfile0[] = "~user/profile0";
712 const char kPurgedMessage[] = "This message should be purged";
713 // Create a profile and push it on the stack, leave one uncreated
714 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
715 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
716
717 // Popping a profile which isn't on top should still clear the log.
718 LOG(INFO) << kPurgedMessage;
719 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
720 kPurgedMessage));
721 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
722 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
723 kPurgedMessage));
724
725 // Popping an invalid profile name should do the same thing.
726 LOG(INFO) << kPurgedMessage;
727 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
728 kPurgedMessage));
729 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
730 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
731 kPurgedMessage));
732
733 // Successful pops also purge the message log.
734 LOG(INFO) << kPurgedMessage;
735 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
736 kPurgedMessage));
737 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
738 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
739 kPurgedMessage));
740}
741
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700742TEST_F(ManagerTest, PushPopProfile) {
743 // It's much easier to use real Glib in creating a Manager for this
744 // test here since we want the storage side-effects.
745 GLib glib;
746 ScopedTempDir temp_dir;
747 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
748 Manager manager(control_interface(),
749 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800750 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700751 &glib,
752 run_path(),
753 storage_path(),
754 temp_dir.path().value());
755
756 // Pushing an invalid profile should fail.
757 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
758
Paul Stewartd0a3b812012-03-28 22:48:22 -0700759 // Pushing a default profile that does not exist should fail.
760 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700761
762 const char kProfile0[] = "~user/profile0";
763 const char kProfile1[] = "~user/profile1";
764
765 // Create a couple of profiles.
766 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
767 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
768
769 // Push these profiles on the stack.
770 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
771 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
772
773 // Pushing a profile a second time should fail.
774 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
775 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
776
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800777 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700778 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800779 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700780
781 // Make sure a profile name that doesn't exist fails.
782 const char kProfile2Id[] = "profile2";
783 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
784 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
785
786 // Create a new service, with a specific storage name.
787 scoped_refptr<MockService> service(
788 new NiceMock<MockService>(control_interface(),
789 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800790 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700791 &manager));
792 const char kServiceName[] = "service_storage_name";
793 EXPECT_CALL(*service.get(), GetStorageIdentifier())
794 .WillRepeatedly(Return(kServiceName));
795 EXPECT_CALL(*service.get(), Load(_))
796 .WillRepeatedly(Return(true));
797
798 // Add this service to the manager -- it should end up in the ephemeral
799 // profile.
800 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800801 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700802
803 // Create storage for a profile that contains the service storage name.
804 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
805 kServiceName));
806
807 // When we push the profile, the service should move away from the
808 // ephemeral profile to this new profile since it has an entry for
809 // this service.
810 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800811 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700812 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
813
814 // Insert another profile that should supersede ownership of the service.
815 const char kProfile3Id[] = "profile3";
816 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
817 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
818 kServiceName));
819 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
820 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
821
822 // Popping an invalid profile name should fail.
823 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
824
825 // Popping an profile that is not at the top of the stack should fail.
826 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
827
828 // Popping the top profile should succeed.
829 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
830
831 // Moreover the service should have switched profiles to profile 2.
832 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
833
834 // Popping the top profile should succeed.
835 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
836
837 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800838 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700839
840 // Pop the remaining two services off the stack.
841 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
842 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
843
844 // Next pop should fail with "stack is empty".
845 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700846
847 const char kMachineProfile0[] = "machineprofile0";
848 const char kMachineProfile1[] = "machineprofile1";
849 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
850 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
851
852 // Should be able to push a machine profile.
853 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
854
855 // Should be able to push a user profile atop a machine profile.
856 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
857
858 // Pushing a system-wide profile on top of a user profile should fail.
859 EXPECT_EQ(Error::kInvalidArguments,
860 TestPushProfile(&manager, kMachineProfile1));
861
862 // However if we pop the user profile, we should be able stack another
863 // machine profile on.
864 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
865 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700866}
867
Paul Stewarte73d05c2012-03-29 16:26:05 -0700868TEST_F(ManagerTest, RemoveProfile) {
869 // It's much easier to use real Glib in creating a Manager for this
870 // test here since we want the storage side-effects.
871 GLib glib;
872 ScopedTempDir temp_dir;
873 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
874 Manager manager(control_interface(),
875 dispatcher(),
876 metrics(),
877 &glib,
878 run_path(),
879 storage_path(),
880 temp_dir.path().value());
881
882 const char kProfile0[] = "profile0";
883 FilePath profile_path(
884 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
885
886 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
887 ASSERT_TRUE(file_util::PathExists(profile_path));
888
889 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
890
891 // Remove should fail since the profile is still on the stack.
892 {
893 Error error;
894 manager.RemoveProfile(kProfile0, &error);
895 EXPECT_EQ(Error::kInvalidArguments, error.type());
896 }
897
898 // Profile path should still exist.
899 EXPECT_TRUE(file_util::PathExists(profile_path));
900
901 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
902
903 // This should succeed now that the profile is off the stack.
904 {
905 Error error;
906 manager.RemoveProfile(kProfile0, &error);
907 EXPECT_EQ(Error::kSuccess, error.type());
908 }
909
910 // Profile path should no longer exist.
911 EXPECT_FALSE(file_util::PathExists(profile_path));
912
913 // Another remove succeeds, due to a foible in file_util::Delete --
914 // it is not an error to delete a file that does not exist.
915 {
916 Error error;
917 manager.RemoveProfile(kProfile0, &error);
918 EXPECT_EQ(Error::kSuccess, error.type());
919 }
920
921 // Let's create an error case that will "work". Create a non-empty
922 // directory in the place of the profile pathname.
923 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
924 {
925 Error error;
926 manager.RemoveProfile(kProfile0, &error);
927 EXPECT_EQ(Error::kOperationFailed, error.type());
928 }
929}
930
Paul Stewartfc9a1da2012-06-27 15:54:52 -0700931TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
932 // It's much easier to use real Glib in creating a Manager for this
933 // test here since we want the storage side-effects.
934 GLib glib;
935 ScopedTempDir temp_dir;
936 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
937 Manager manager(control_interface(),
938 dispatcher(),
939 metrics(),
940 &glib,
941 run_path(),
942 storage_path(),
943 temp_dir.path().value());
944
945 const char kProfile0[] = "profile0";
946 FilePath profile_path(
947 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
948
949 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
950 ASSERT_TRUE(file_util::PathExists(profile_path));
951 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
952
953 // Ensure that even if the backing filestore is removed, we still can't
954 // create a profile twice.
955 ASSERT_TRUE(file_util::Delete(profile_path, false));
956 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
957}
958
Paul Stewart75225512012-01-26 22:51:33 -0800959// Use this matcher instead of passing RefPtrs directly into the arguments
960// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
961// system teardown.
962MATCHER_P(IsRefPtrTo, ref_address, "") {
963 return arg.get() == ref_address;
964}
965
966TEST_F(ManagerTest, HandleProfileEntryDeletion) {
967 MockServiceRefPtr s_not_in_profile(
968 new NiceMock<MockService>(control_interface(),
969 dispatcher(),
970 metrics(),
971 manager()));
972 MockServiceRefPtr s_not_in_group(
973 new NiceMock<MockService>(control_interface(),
974 dispatcher(),
975 metrics(),
976 manager()));
977 MockServiceRefPtr s_configure_fail(
978 new NiceMock<MockService>(control_interface(),
979 dispatcher(),
980 metrics(),
981 manager()));
982 MockServiceRefPtr s_configure_succeed(
983 new NiceMock<MockService>(control_interface(),
984 dispatcher(),
985 metrics(),
986 manager()));
987
988 string entry_name("entry_name");
989 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
990 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
991 .WillRepeatedly(Return("not_entry_name"));
992 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
993 .WillRepeatedly(Return(entry_name));
994 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
995 .WillRepeatedly(Return(entry_name));
996
997 manager()->RegisterService(s_not_in_profile);
998 manager()->RegisterService(s_not_in_group);
999 manager()->RegisterService(s_configure_fail);
1000 manager()->RegisterService(s_configure_succeed);
1001
1002 scoped_refptr<MockProfile> profile0(
1003 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1004 scoped_refptr<MockProfile> profile1(
1005 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1006
1007 s_not_in_group->set_profile(profile1);
1008 s_configure_fail->set_profile(profile1);
1009 s_configure_succeed->set_profile(profile1);
1010
1011 AdoptProfile(manager(), profile0);
1012 AdoptProfile(manager(), profile1);
1013
1014 // No services are a member of this profile.
1015 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1016
1017 // No services that are members of this profile have this entry name.
1018 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1019
1020 // Only services that are members of the profile and group will be abandoned.
1021 EXPECT_CALL(*profile1.get(),
1022 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1023 EXPECT_CALL(*profile1.get(),
1024 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1025 EXPECT_CALL(*profile1.get(),
1026 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1027 .WillOnce(Return(true));
1028 EXPECT_CALL(*profile1.get(),
1029 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1030 .WillOnce(Return(true));
1031
1032 // Never allow services to re-join profile1.
1033 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1034 .WillRepeatedly(Return(false));
1035
1036 // Only allow one of the members of the profile and group to successfully
1037 // join profile0.
1038 EXPECT_CALL(*profile0.get(),
1039 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1040 EXPECT_CALL(*profile0.get(),
1041 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1042 EXPECT_CALL(*profile0.get(),
1043 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1044 .WillOnce(Return(false));
1045 EXPECT_CALL(*profile0.get(),
1046 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1047 .WillOnce(Return(true));
1048
1049 // Expect the failed-to-configure service to have Unload() called on it.
1050 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1051 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1052 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1053 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1054
1055 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1056
1057 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1058 EXPECT_EQ(profile1, s_not_in_group->profile());
1059 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1060
1061 // Since we are using a MockProfile, the profile does not actually change,
1062 // since ConfigureService was not actually called on the service.
1063 EXPECT_EQ(profile1, s_configure_succeed->profile());
1064}
1065
Paul Stewart65512e12012-03-26 18:01:08 -07001066TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1067 MockServiceRefPtr s_will_remove0(
1068 new NiceMock<MockService>(control_interface(),
1069 dispatcher(),
1070 metrics(),
1071 manager()));
1072 MockServiceRefPtr s_will_remove1(
1073 new NiceMock<MockService>(control_interface(),
1074 dispatcher(),
1075 metrics(),
1076 manager()));
1077 MockServiceRefPtr s_will_not_remove0(
1078 new NiceMock<MockService>(control_interface(),
1079 dispatcher(),
1080 metrics(),
1081 manager()));
1082 MockServiceRefPtr s_will_not_remove1(
1083 new NiceMock<MockService>(control_interface(),
1084 dispatcher(),
1085 metrics(),
1086 manager()));
1087
1088 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1089 .Times(4); // Once for each registration.
1090
1091 string entry_name("entry_name");
1092 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1093 .WillRepeatedly(Return(entry_name));
1094 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1095 .WillRepeatedly(Return(entry_name));
1096 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1097 .WillRepeatedly(Return(entry_name));
1098 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1099 .WillRepeatedly(Return(entry_name));
1100
1101 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001102 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001103 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001104 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001105 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001106 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001107 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001108 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001109
1110 // One for each service added above.
1111 ASSERT_EQ(4, manager()->services_.size());
1112
1113 scoped_refptr<MockProfile> profile(
1114 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1115
1116 s_will_remove0->set_profile(profile);
1117 s_will_remove1->set_profile(profile);
1118 s_will_not_remove0->set_profile(profile);
1119 s_will_not_remove1->set_profile(profile);
1120
1121 AdoptProfile(manager(), profile);
1122
1123 // Deny any of the services re-entry to the profile.
1124 EXPECT_CALL(*profile, ConfigureService(_))
1125 .WillRepeatedly(Return(false));
1126
1127 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1128 .WillOnce(Return(true));
1129 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1130 .WillOnce(Return(true));
1131 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1132 .WillOnce(Return(true));
1133 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1134 .WillOnce(Return(true));
1135
1136 EXPECT_CALL(*s_will_remove0, Unload())
1137 .WillOnce(Return(true));
1138 EXPECT_CALL(*s_will_remove1, Unload())
1139 .WillOnce(Return(true));
1140 EXPECT_CALL(*s_will_not_remove0, Unload())
1141 .WillOnce(Return(false));
1142 EXPECT_CALL(*s_will_not_remove1, Unload())
1143 .WillOnce(Return(false));
1144
1145
1146 // This will cause all the profiles to be unloaded.
1147 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1148
1149 // 2 of the 4 services added above should have been unregistered and
1150 // removed, leaving 2.
1151 EXPECT_EQ(2, manager()->services_.size());
1152 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1153 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1154}
1155
1156TEST_F(ManagerTest, PopProfileWithUnload) {
1157 MockServiceRefPtr s_will_remove0(
1158 new NiceMock<MockService>(control_interface(),
1159 dispatcher(),
1160 metrics(),
1161 manager()));
1162 MockServiceRefPtr s_will_remove1(
1163 new NiceMock<MockService>(control_interface(),
1164 dispatcher(),
1165 metrics(),
1166 manager()));
1167 MockServiceRefPtr s_will_not_remove0(
1168 new NiceMock<MockService>(control_interface(),
1169 dispatcher(),
1170 metrics(),
1171 manager()));
1172 MockServiceRefPtr s_will_not_remove1(
1173 new NiceMock<MockService>(control_interface(),
1174 dispatcher(),
1175 metrics(),
1176 manager()));
1177
1178 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1179 .Times(5); // Once for each registration, and one after profile pop.
1180
1181 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001182 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001183 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001184 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001185 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001186 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001187 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001188 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001189
1190 // One for each service added above.
1191 ASSERT_EQ(4, manager()->services_.size());
1192
1193 scoped_refptr<MockProfile> profile0(
1194 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1195 scoped_refptr<MockProfile> profile1(
1196 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1197
1198 s_will_remove0->set_profile(profile1);
1199 s_will_remove1->set_profile(profile1);
1200 s_will_not_remove0->set_profile(profile1);
1201 s_will_not_remove1->set_profile(profile1);
1202
1203 AdoptProfile(manager(), profile0);
1204 AdoptProfile(manager(), profile1);
1205
1206 // Deny any of the services entry to profile0, so they will all be unloaded.
1207 EXPECT_CALL(*profile0, ConfigureService(_))
1208 .WillRepeatedly(Return(false));
1209
1210 EXPECT_CALL(*s_will_remove0, Unload())
1211 .WillOnce(Return(true));
1212 EXPECT_CALL(*s_will_remove1, Unload())
1213 .WillOnce(Return(true));
1214 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001215 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001216 EXPECT_CALL(*s_will_not_remove1, Unload())
1217 .WillOnce(Return(false));
1218
1219 // This will pop profile1, which should cause all our profiles to unload.
1220 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001221 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001222
1223 // 2 of the 4 services added above should have been unregistered and
1224 // removed, leaving 2.
1225 EXPECT_EQ(2, manager()->services_.size());
1226 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1227 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001228
1229 // Expect the unloaded services to lose their profile reference.
1230 EXPECT_FALSE(s_will_remove0->profile());
1231 EXPECT_FALSE(s_will_remove1->profile());
1232
1233 // If we explicitly deregister a service, the effect should be the same
1234 // with respect to the profile reference.
1235 ASSERT_TRUE(s_will_not_remove0->profile());
1236 manager()->DeregisterService(s_will_not_remove0);
1237 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001238}
1239
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001240TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001241 {
1242 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001243 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1244 flimflam::kOfflineModeProperty,
1245 PropertyStoreTest::kBoolV,
1246 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001247 }
1248 {
1249 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001250 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1251 flimflam::kCountryProperty,
1252 PropertyStoreTest::kStringV,
1253 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001254 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001255 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001256 {
1257 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001258 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1259 flimflam::kCountryProperty,
1260 PropertyStoreTest::kBoolV,
1261 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001262 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001263 }
1264 {
1265 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001266 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1267 flimflam::kOfflineModeProperty,
1268 PropertyStoreTest::kStringV,
1269 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001270 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001271 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001272 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001273 {
1274 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001275 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001276 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001277 flimflam::kEnabledTechnologiesProperty,
1278 PropertyStoreTest::kStringsV,
1279 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001280 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001281 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001282}
1283
mukesh agrawal32399322011-09-01 10:53:43 -07001284TEST_F(ManagerTest, RequestScan) {
1285 {
1286 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001287 manager()->RegisterDevice(mock_devices_[0].get());
1288 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001289 EXPECT_CALL(*mock_devices_[0], technology())
1290 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001291 EXPECT_CALL(*mock_devices_[0], Scan(_));
Joshua Krollda798622012-06-05 12:30:48 -07001292 EXPECT_CALL(*mock_devices_[1], technology())
1293 .WillRepeatedly(Return(Technology::kUnknown));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001294 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001295 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001296 }
1297
1298 {
1299 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001300 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001301 EXPECT_EQ(Error::kInvalidArguments, error.type());
1302 }
1303}
1304
Darin Petkovb65c2452012-02-23 15:17:06 +01001305TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001306 KeyValueStore args;
1307 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001308 manager()->GetService(args, &e);
1309 EXPECT_EQ(Error::kInvalidArguments, e.type());
1310 EXPECT_EQ("must specify service type", e.message());
1311}
1312
1313TEST_F(ManagerTest, GetServiceUnknownType) {
1314 KeyValueStore args;
1315 Error e;
1316 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1317 manager()->GetService(args, &e);
1318 EXPECT_EQ(Error::kNotSupported, e.type());
1319 EXPECT_EQ("service type is unsupported", e.message());
1320}
1321
1322TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1323 KeyValueStore args;
1324 Error e;
1325 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1326 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001327 EXPECT_EQ(Error::kInvalidArguments, e.type());
1328 EXPECT_EQ("no wifi devices available", e.message());
1329}
1330
Darin Petkovb65c2452012-02-23 15:17:06 +01001331TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001332 KeyValueStore args;
1333 Error e;
1334 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001335 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001336 manager()->RegisterDevice(mock_wifi_);
1337 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1338 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001339 manager()->GetService(args, &e);
1340 EXPECT_TRUE(e.IsSuccess());
1341}
1342
Darin Petkov33af05c2012-02-28 10:10:30 +01001343TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1344 KeyValueStore args;
1345 Error e;
1346 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001347 scoped_refptr<MockProfile> profile(
1348 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1349 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001350 ServiceRefPtr service = manager()->GetService(args, &e);
1351 EXPECT_EQ(Error::kNotSupported, e.type());
1352 EXPECT_FALSE(service);
1353}
1354
Darin Petkovb65c2452012-02-23 15:17:06 +01001355TEST_F(ManagerTest, GetServiceVPN) {
1356 KeyValueStore args;
1357 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001358 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001359 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001360 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1361 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001362 scoped_refptr<MockProfile> profile(
1363 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1364 AdoptProfile(manager(), profile);
1365 ServiceRefPtr updated_service;
1366 EXPECT_CALL(*profile, UpdateService(_))
1367 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1368 ServiceRefPtr configured_service;
1369 EXPECT_CALL(*profile, ConfigureService(_))
1370 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001371 ServiceRefPtr service = manager()->GetService(args, &e);
1372 EXPECT_TRUE(e.IsSuccess());
1373 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001374 EXPECT_EQ(service, updated_service);
1375 EXPECT_EQ(service, configured_service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001376}
1377
Darin Petkovc63dcf02012-05-24 11:51:43 +02001378TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1379 KeyValueStore args;
1380 Error e;
1381 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1382 ServiceRefPtr service = manager()->GetService(args, &e);
1383 EXPECT_EQ(Error::kInvalidArguments, e.type());
1384 EXPECT_EQ("Missing WiMAX network id.", e.message());
1385 EXPECT_FALSE(service);
1386}
1387
Darin Petkovd1cd7972012-05-22 15:26:15 +02001388TEST_F(ManagerTest, GetServiceWiMax) {
1389 KeyValueStore args;
1390 Error e;
1391 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001392 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1393 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1394 ServiceRefPtr service = manager()->GetService(args, &e);
1395 EXPECT_TRUE(e.IsSuccess());
1396 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001397}
1398
Paul Stewart7f61e522012-03-22 11:13:45 -07001399TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1400 // Manager calls ActiveProfile() so we need at least one profile installed.
1401 scoped_refptr<MockProfile> profile(
1402 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1403 AdoptProfile(manager(), profile);
1404
1405 KeyValueStore args;
1406 args.SetString(flimflam::kProfileProperty, "xxx");
1407 Error error;
1408 manager()->ConfigureService(args, &error);
1409 EXPECT_EQ(Error::kInvalidArguments, error.type());
1410 EXPECT_EQ("Invalid profile name xxx", error.message());
1411}
1412
1413TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1414 // Manager calls ActiveProfile() so we need at least one profile installed.
1415 scoped_refptr<MockProfile> profile(
1416 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1417 AdoptProfile(manager(), profile);
1418
1419 KeyValueStore args;
1420 Error error;
1421 manager()->ConfigureService(args, &error);
1422 EXPECT_EQ(Error::kInvalidArguments, error.type());
1423 EXPECT_EQ("must specify service type", error.message());
1424}
1425
1426// A registered service in the ephemeral profile should be moved to the
1427// active profile as a part of configuration if no profile was explicitly
1428// specified.
1429TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1430 scoped_refptr<MockProfile> profile(
1431 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1432
1433 AdoptProfile(manager(), profile); // This is now the active profile.
1434
1435 const std::vector<uint8_t> ssid;
1436 scoped_refptr<MockWiFiService> service(
1437 new NiceMock<MockWiFiService>(control_interface(),
1438 dispatcher(),
1439 metrics(),
1440 manager(),
1441 mock_wifi_,
1442 ssid,
1443 "",
1444 "",
1445 false));
1446
1447 manager()->RegisterService(service);
1448 service->set_profile(GetEphemeralProfile(manager()));
1449
1450 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1451 // the same device as that used above causes a refcounting loop.
1452 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1453 dispatcher(),
1454 metrics(),
1455 manager(),
1456 "wifi1",
1457 "addr5",
1458 5));
1459 manager()->RegisterDevice(wifi);
1460 EXPECT_CALL(*wifi, GetService(_, _))
1461 .WillOnce(Return(service));
1462 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1463 .WillOnce(Return(true));
1464 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1465 .WillOnce(Return(true));
1466
1467 KeyValueStore args;
1468 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1469 Error error;
1470 manager()->ConfigureService(args, &error);
1471 EXPECT_TRUE(error.IsSuccess());
1472}
1473
1474// If were configure a service that was already registered and explicitly
1475// specify a profile, it should be moved from the profile it was previously
1476// in to the specified profile if one was requested.
1477TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1478 scoped_refptr<MockProfile> profile0(
1479 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1480 scoped_refptr<MockProfile> profile1(
1481 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1482
1483 const string kProfileName0 = "profile0";
1484 const string kProfileName1 = "profile1";
1485
1486 EXPECT_CALL(*profile0, GetRpcIdentifier())
1487 .WillRepeatedly(Return(kProfileName0));
1488 EXPECT_CALL(*profile1, GetRpcIdentifier())
1489 .WillRepeatedly(Return(kProfileName1));
1490
1491 AdoptProfile(manager(), profile0);
1492 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1493
1494 const std::vector<uint8_t> ssid;
1495 scoped_refptr<MockWiFiService> service(
1496 new NiceMock<MockWiFiService>(control_interface(),
1497 dispatcher(),
1498 metrics(),
1499 manager(),
1500 mock_wifi_,
1501 ssid,
1502 "",
1503 "",
1504 false));
1505
1506 manager()->RegisterService(service);
1507 service->set_profile(profile1);
1508
1509 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1510 // the same device as that used above causes a refcounting loop.
1511 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1512 dispatcher(),
1513 metrics(),
1514 manager(),
1515 "wifi1",
1516 "addr5",
1517 5));
1518 manager()->RegisterDevice(wifi);
1519 EXPECT_CALL(*wifi, GetService(_, _))
1520 .WillOnce(Return(service));
1521 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1522 .WillOnce(Return(true));
1523 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1524 .WillOnce(Return(true));
1525 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1526 .WillOnce(Return(true));
1527
1528 KeyValueStore args;
1529 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1530 args.SetString(flimflam::kProfileProperty, kProfileName0);
1531 Error error;
1532 manager()->ConfigureService(args, &error);
1533 EXPECT_TRUE(error.IsSuccess());
1534 service->set_profile(NULL); // Breaks refcounting loop.
1535}
1536
1537// An unregistered service should remain unregistered, but its contents should
1538// be saved to the specified profile nonetheless.
1539TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1540 scoped_refptr<MockProfile> profile0(
1541 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1542 scoped_refptr<MockProfile> profile1(
1543 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1544
1545 const string kProfileName0 = "profile0";
1546 const string kProfileName1 = "profile1";
1547
1548 EXPECT_CALL(*profile0, GetRpcIdentifier())
1549 .WillRepeatedly(Return(kProfileName0));
1550 EXPECT_CALL(*profile1, GetRpcIdentifier())
1551 .WillRepeatedly(Return(kProfileName1));
1552
1553 AdoptProfile(manager(), profile0);
1554 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1555
1556 const std::vector<uint8_t> ssid;
1557 scoped_refptr<MockWiFiService> service(
1558 new NiceMock<MockWiFiService>(control_interface(),
1559 dispatcher(),
1560 metrics(),
1561 manager(),
1562 mock_wifi_,
1563 ssid,
1564 "",
1565 "",
1566 false));
1567
1568 service->set_profile(profile1);
1569
1570 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1571 // the same device as that used above causes a refcounting loop.
1572 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1573 dispatcher(),
1574 metrics(),
1575 manager(),
1576 "wifi1",
1577 "addr5",
1578 5));
1579 manager()->RegisterDevice(wifi);
1580 EXPECT_CALL(*wifi, GetService(_, _))
1581 .WillOnce(Return(service));
1582 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1583 .WillOnce(Return(true));
1584 EXPECT_CALL(*profile0, AdoptService(_))
1585 .Times(0);
1586 EXPECT_CALL(*profile1, AdoptService(_))
1587 .Times(0);
1588
1589 KeyValueStore args;
1590 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1591 args.SetString(flimflam::kProfileProperty, kProfileName0);
1592 Error error;
1593 manager()->ConfigureService(args, &error);
1594 EXPECT_TRUE(error.IsSuccess());
1595}
1596
Paul Stewart22aa71b2011-09-16 12:15:11 -07001597TEST_F(ManagerTest, TechnologyOrder) {
1598 Error error;
1599 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1600 string(flimflam::kTypeWifi), &error);
1601 ASSERT_TRUE(error.IsSuccess());
1602 EXPECT_EQ(manager()->GetTechnologyOrder(),
1603 string(flimflam::kTypeEthernet) + "," +
1604 string(flimflam::kTypeWifi));
1605
1606 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1607 string(flimflam::kTypeWifi), &error);
1608 ASSERT_FALSE(error.IsSuccess());
1609 EXPECT_EQ(Error::kInvalidArguments, error.type());
1610 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1611 string(flimflam::kTypeWifi),
1612 manager()->GetTechnologyOrder());
1613}
1614
1615TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001616 // TODO(quiche): Some of these tests would probably fit better in
1617 // service_unittest, since the actual comparison of Services is
1618 // implemented in Service. (crosbug.com/23370)
1619
Paul Stewart22aa71b2011-09-16 12:15:11 -07001620 scoped_refptr<MockService> mock_service0(
1621 new NiceMock<MockService>(control_interface(),
1622 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001623 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001624 manager()));
1625 scoped_refptr<MockService> mock_service1(
1626 new NiceMock<MockService>(control_interface(),
1627 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001628 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001629 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001630
1631 manager()->RegisterService(mock_service0);
1632 manager()->RegisterService(mock_service1);
1633
1634 // Services should already be sorted by UniqueName
1635 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1636
1637 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07001638 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001639 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1640
1641 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001642 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001643 manager()->UpdateService(mock_service1);
1644 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1645
1646 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001647 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001648 manager()->UpdateService(mock_service0);
1649 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1650
1651 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07001652 EXPECT_CALL(*mock_service0.get(), technology())
1653 .WillRepeatedly(Return((Technology::kWifi)));
1654 EXPECT_CALL(*mock_service1.get(), technology())
1655 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001656
1657 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001658 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07001659 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001660 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1661
1662 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1663 string(flimflam::kTypeEthernet), &error);
1664 EXPECT_TRUE(error.IsSuccess());
1665 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1666
Gaurav Shah435de2c2011-11-17 19:01:07 -08001667 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001668 mock_service0->set_priority(1);
1669 manager()->UpdateService(mock_service0);
1670 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1671
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001672 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001673 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001674 manager()->UpdateService(mock_service1);
1675 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1676
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001677 // Auto-connect.
1678 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001679 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001680 mock_service1->set_auto_connect(false);
1681 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001682 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1683
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001684 // Connectable.
1685 mock_service1->set_connectable(true);
1686 manager()->UpdateService(mock_service1);
1687 mock_service0->set_connectable(false);
1688 manager()->UpdateService(mock_service0);
1689 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1690
1691 // IsFailed.
1692 EXPECT_CALL(*mock_service0.get(), state())
1693 .WillRepeatedly(Return(Service::kStateIdle));
1694 EXPECT_CALL(*mock_service0.get(), IsFailed())
1695 .WillRepeatedly(Return(false));
1696 manager()->UpdateService(mock_service0);
1697 EXPECT_CALL(*mock_service0.get(), state())
1698 .WillRepeatedly(Return(Service::kStateFailure));
1699 EXPECT_CALL(*mock_service1.get(), IsFailed())
1700 .WillRepeatedly(Return(true));
1701 manager()->UpdateService(mock_service1);
1702 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1703
1704 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001705 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001706 .WillRepeatedly(Return(Service::kStateAssociating));
1707 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001708 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001709 manager()->UpdateService(mock_service1);
1710 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1711
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001712 // Connected.
1713 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07001714 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001715 EXPECT_CALL(*mock_service0.get(), IsConnected())
1716 .WillRepeatedly(Return(true));
1717 manager()->UpdateService(mock_service0);
1718 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1719
Paul Stewarta121c442012-06-09 14:12:58 -07001720 // Portal.
1721 EXPECT_CALL(*mock_service1.get(), state())
1722 .WillRepeatedly(Return(Service::kStateConnected));
1723 EXPECT_CALL(*mock_service1.get(), IsConnected())
1724 .WillRepeatedly(Return(true));
1725 manager()->UpdateService(mock_service1);
1726 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1727
Paul Stewart22aa71b2011-09-16 12:15:11 -07001728 manager()->DeregisterService(mock_service0);
1729 manager()->DeregisterService(mock_service1);
1730}
1731
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001732TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001733 MockMetrics mock_metrics;
1734 manager()->set_metrics(&mock_metrics);
1735
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001736 scoped_refptr<MockService> mock_service0(
1737 new NiceMock<MockService>(control_interface(),
1738 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001739 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001740 manager()));
1741 scoped_refptr<MockService> mock_service1(
1742 new NiceMock<MockService>(control_interface(),
1743 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001744 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001745 manager()));
1746
1747 scoped_refptr<MockConnection> mock_connection0(
1748 new NiceMock<MockConnection>(device_info_.get()));
1749 scoped_refptr<MockConnection> mock_connection1(
1750 new NiceMock<MockConnection>(device_info_.get()));
1751
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001752 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001753 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001754 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001755 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001756 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001757 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001758
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001759 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07001760 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001761
1762 mock_service1->set_priority(1);
1763 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07001764 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001765
1766 mock_service1->set_priority(0);
1767 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07001768 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001769
Paul Stewartce4ec192012-03-14 12:53:46 -07001770 mock_service0->set_mock_connection(mock_connection0);
1771 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001772
1773 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001774 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07001775 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001776
Darin Petkova5e07ef2012-07-09 14:27:57 +02001777 ServiceWatcher service_watcher;
1778 int tag =
1779 manager()->RegisterDefaultServiceCallback(
1780 Bind(&ServiceWatcher::OnDefaultServiceChanged,
1781 service_watcher.AsWeakPtr()));
1782 EXPECT_EQ(1, tag);
1783
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001784 mock_service1->set_priority(1);
1785 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1786 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02001787 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00001788 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07001789 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001790
Darin Petkova5e07ef2012-07-09 14:27:57 +02001791 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001792 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02001793 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00001794 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001795 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001796 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001797 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001798
Paul Stewartce4ec192012-03-14 12:53:46 -07001799 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001800 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001801 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001802 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001803
1804 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07001805 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001806}
1807
Darin Petkova5e07ef2012-07-09 14:27:57 +02001808TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
1809 EXPECT_EQ(0, manager()->default_service_callback_tag_);
1810 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
1811
1812 MockMetrics mock_metrics;
1813 manager()->set_metrics(&mock_metrics);
1814
1815 scoped_refptr<MockService> mock_service(
1816 new NiceMock<MockService>(
1817 control_interface(), dispatcher(), metrics(), manager()));
1818 ServiceRefPtr service = mock_service;
1819 ServiceRefPtr null_service;
1820
1821 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1822 manager()->NotifyDefaultServiceChanged(null_service);
1823
1824 ServiceWatcher service_watcher1;
1825 ServiceWatcher service_watcher2;
1826 int tag1 =
1827 manager()->RegisterDefaultServiceCallback(
1828 Bind(&ServiceWatcher::OnDefaultServiceChanged,
1829 service_watcher1.AsWeakPtr()));
1830 EXPECT_EQ(1, tag1);
1831 int tag2 =
1832 manager()->RegisterDefaultServiceCallback(
1833 Bind(&ServiceWatcher::OnDefaultServiceChanged,
1834 service_watcher2.AsWeakPtr()));
1835 EXPECT_EQ(2, tag2);
1836
1837 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
1838 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
1839 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1840 manager()->NotifyDefaultServiceChanged(null_service);
1841
1842 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
1843 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
1844 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
1845 manager()->NotifyDefaultServiceChanged(mock_service);
1846
1847 manager()->DeregisterDefaultServiceCallback(tag1);
1848 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
1849 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
1850 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
1851 manager()->NotifyDefaultServiceChanged(mock_service);
1852 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
1853
1854 manager()->DeregisterDefaultServiceCallback(tag2);
1855 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
1856 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
1857 manager()->NotifyDefaultServiceChanged(mock_service);
1858
1859 EXPECT_EQ(2, manager()->default_service_callback_tag_);
1860 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
1861}
1862
Gaurav Shah435de2c2011-11-17 19:01:07 -08001863TEST_F(ManagerTest, AvailableTechnologies) {
1864 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1865 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001866 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001867 manager(),
1868 "null4",
1869 "addr4",
1870 0));
1871 manager()->RegisterDevice(mock_devices_[0]);
1872 manager()->RegisterDevice(mock_devices_[1]);
1873 manager()->RegisterDevice(mock_devices_[2]);
1874 manager()->RegisterDevice(mock_devices_[3]);
1875
1876 ON_CALL(*mock_devices_[0].get(), technology())
1877 .WillByDefault(Return(Technology::kEthernet));
1878 ON_CALL(*mock_devices_[1].get(), technology())
1879 .WillByDefault(Return(Technology::kWifi));
1880 ON_CALL(*mock_devices_[2].get(), technology())
1881 .WillByDefault(Return(Technology::kCellular));
1882 ON_CALL(*mock_devices_[3].get(), technology())
1883 .WillByDefault(Return(Technology::kWifi));
1884
1885 set<string> expected_technologies;
1886 expected_technologies.insert(Technology::NameFromIdentifier(
1887 Technology::kEthernet));
1888 expected_technologies.insert(Technology::NameFromIdentifier(
1889 Technology::kWifi));
1890 expected_technologies.insert(Technology::NameFromIdentifier(
1891 Technology::kCellular));
1892 Error error;
1893 vector<string> technologies = manager()->AvailableTechnologies(&error);
1894
1895 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1896 ContainerEq(expected_technologies));
1897}
1898
1899TEST_F(ManagerTest, ConnectedTechnologies) {
1900 scoped_refptr<MockService> connected_service1(
1901 new NiceMock<MockService>(control_interface(),
1902 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001903 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001904 manager()));
1905 scoped_refptr<MockService> connected_service2(
1906 new NiceMock<MockService>(control_interface(),
1907 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001908 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001909 manager()));
1910 scoped_refptr<MockService> disconnected_service1(
1911 new NiceMock<MockService>(control_interface(),
1912 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001913 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001914 manager()));
1915 scoped_refptr<MockService> disconnected_service2(
1916 new NiceMock<MockService>(control_interface(),
1917 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001918 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001919 manager()));
1920
1921 ON_CALL(*connected_service1.get(), IsConnected())
1922 .WillByDefault(Return(true));
1923 ON_CALL(*connected_service2.get(), IsConnected())
1924 .WillByDefault(Return(true));
1925
1926 manager()->RegisterService(connected_service1);
1927 manager()->RegisterService(connected_service2);
1928 manager()->RegisterService(disconnected_service1);
1929 manager()->RegisterService(disconnected_service2);
1930
1931 manager()->RegisterDevice(mock_devices_[0]);
1932 manager()->RegisterDevice(mock_devices_[1]);
1933 manager()->RegisterDevice(mock_devices_[2]);
1934 manager()->RegisterDevice(mock_devices_[3]);
1935
1936 ON_CALL(*mock_devices_[0].get(), technology())
1937 .WillByDefault(Return(Technology::kEthernet));
1938 ON_CALL(*mock_devices_[1].get(), technology())
1939 .WillByDefault(Return(Technology::kWifi));
1940 ON_CALL(*mock_devices_[2].get(), technology())
1941 .WillByDefault(Return(Technology::kCellular));
1942 ON_CALL(*mock_devices_[3].get(), technology())
1943 .WillByDefault(Return(Technology::kWifi));
1944
1945 mock_devices_[0]->SelectService(connected_service1);
1946 mock_devices_[1]->SelectService(disconnected_service1);
1947 mock_devices_[2]->SelectService(disconnected_service2);
1948 mock_devices_[3]->SelectService(connected_service2);
1949
1950 set<string> expected_technologies;
1951 expected_technologies.insert(Technology::NameFromIdentifier(
1952 Technology::kEthernet));
1953 expected_technologies.insert(Technology::NameFromIdentifier(
1954 Technology::kWifi));
1955 Error error;
1956
1957 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1958 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1959 ContainerEq(expected_technologies));
1960}
1961
1962TEST_F(ManagerTest, DefaultTechnology) {
1963 scoped_refptr<MockService> connected_service(
1964 new NiceMock<MockService>(control_interface(),
1965 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001966 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001967 manager()));
1968 scoped_refptr<MockService> disconnected_service(
1969 new NiceMock<MockService>(control_interface(),
1970 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001971 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001972 manager()));
1973
1974 // Connected. WiFi.
1975 ON_CALL(*connected_service.get(), IsConnected())
1976 .WillByDefault(Return(true));
1977 ON_CALL(*connected_service.get(), state())
1978 .WillByDefault(Return(Service::kStateConnected));
1979 ON_CALL(*connected_service.get(), technology())
1980 .WillByDefault(Return(Technology::kWifi));
1981
1982 // Disconnected. Ethernet.
1983 ON_CALL(*disconnected_service.get(), technology())
1984 .WillByDefault(Return(Technology::kEthernet));
1985
1986 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07001987 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08001988 Error error;
1989 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1990
1991
1992 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07001993 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08001994 // Connected service should be brought to the front now.
1995 string expected_technology =
1996 Technology::NameFromIdentifier(Technology::kWifi);
1997 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1998}
1999
Paul Stewart212d60f2012-07-12 10:59:13 -07002000TEST_F(ManagerTest, Stop) {
2001 scoped_refptr<MockProfile> profile(
2002 new NiceMock<MockProfile>(control_interface(), manager(), ""));
2003 AdoptProfile(manager(), profile);
2004 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002005 new NiceMock<MockService>(control_interface(),
2006 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002007 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002008 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002009 manager()->RegisterService(service);
2010 manager()->RegisterDevice(mock_devices_[0]);
2011 EXPECT_CALL(*profile.get(),
2012 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2013 .WillOnce(Return(true));
2014 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2015 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002016 manager()->Stop();
2017}
2018
mukesh agrawal00917ce2011-11-22 23:56:55 +00002019TEST_F(ManagerTest, UpdateServiceConnected) {
2020 scoped_refptr<MockService> mock_service(
2021 new NiceMock<MockService>(control_interface(),
2022 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002023 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002024 manager()));
2025 manager()->RegisterService(mock_service);
2026 EXPECT_FALSE(mock_service->favorite());
2027 EXPECT_FALSE(mock_service->auto_connect());
2028
Gaurav Shah435de2c2011-11-17 19:01:07 -08002029 EXPECT_CALL(*mock_service.get(), IsConnected())
2030 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002031 manager()->UpdateService(mock_service);
2032 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2033 // to mock out MakeFavorite. And mocking that out would break the
2034 // SortServices test. (crosbug.com/23370)
2035 EXPECT_TRUE(mock_service->favorite());
2036 EXPECT_TRUE(mock_service->auto_connect());
2037}
2038
Thieu Led4e9e552012-02-16 16:26:07 -08002039TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2040 // This tests the case where the user connects to a service that is
2041 // currently associated with a profile. We want to make sure that the
2042 // favorite flag is set and that the flag is saved to the current
2043 // profile.
2044 scoped_refptr<MockService> mock_service(
2045 new NiceMock<MockService>(control_interface(),
2046 dispatcher(),
2047 metrics(),
2048 manager()));
2049 manager()->RegisterService(mock_service);
2050 EXPECT_FALSE(mock_service->favorite());
2051 EXPECT_FALSE(mock_service->auto_connect());
2052
Gary Moraind93615e2012-04-27 11:50:03 -07002053 scoped_refptr<MockProfile> profile(
2054 new MockProfile(control_interface(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002055
Gary Moraind93615e2012-04-27 11:50:03 -07002056 mock_service->set_profile(profile);
2057 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002058 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002059 EXPECT_CALL(*profile,
2060 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002061 manager()->UpdateService(mock_service);
2062 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2063 // to mock out MakeFavorite. And mocking that out would break the
2064 // SortServices test. (crosbug.com/23370)
2065 EXPECT_TRUE(mock_service->favorite());
2066 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002067 // This releases the ref on the mock profile.
2068 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002069}
2070
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002071TEST_F(ManagerTest, SaveSuccessfulService) {
2072 scoped_refptr<MockProfile> profile(
2073 new StrictMock<MockProfile>(control_interface(), manager(), ""));
2074 AdoptProfile(manager(), profile);
2075 scoped_refptr<MockService> service(
2076 new NiceMock<MockService>(control_interface(),
2077 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002078 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002079 manager()));
2080
2081 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2082 ServiceRefPtr expect_service(service.get());
2083
2084 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2085 .WillOnce(Return(false));
2086 manager()->RegisterService(service);
2087
2088 EXPECT_CALL(*service.get(), state())
2089 .WillRepeatedly(Return(Service::kStateConnected));
2090 EXPECT_CALL(*service.get(), IsConnected())
2091 .WillRepeatedly(Return(true));
2092 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2093 .WillOnce(Return(true));
2094 manager()->UpdateService(service);
2095}
2096
Darin Petkove7c6ad32012-06-29 10:22:09 +02002097TEST_F(ManagerTest, UpdateDevice) {
2098 MockProfile *profile0 = new MockProfile(control_interface(), manager(), "");
2099 MockProfile *profile1 = new MockProfile(control_interface(), manager(), "");
2100 MockProfile *profile2 = new MockProfile(control_interface(), manager(), "");
2101 AdoptProfile(manager(), profile0); // Passes ownership.
2102 AdoptProfile(manager(), profile1); // Passes ownership.
2103 AdoptProfile(manager(), profile2); // Passes ownership.
2104 DeviceRefPtr device_ref(mock_devices_[0].get());
2105 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2106 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2107 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2108 manager()->UpdateDevice(mock_devices_[0]);
2109}
2110
Paul Stewart1b253142012-01-26 14:05:52 -08002111TEST_F(ManagerTest, EnumerateProfiles) {
2112 vector<string> profile_paths;
2113 for (size_t i = 0; i < 10; i++) {
2114 scoped_refptr<MockProfile> profile(
2115 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002116 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002117 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2118 .WillOnce(Return(profile_paths.back()));
2119 AdoptProfile(manager(), profile);
2120 }
2121
2122 Error error;
2123 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2124 EXPECT_TRUE(error.IsSuccess());
2125 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2126 for (size_t i = 0; i < profile_paths.size(); i++) {
2127 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2128 }
2129}
2130
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002131TEST_F(ManagerTest, AutoConnectOnRegister) {
2132 MockServiceRefPtr service = MakeAutoConnectableService();
2133 EXPECT_CALL(*service.get(), AutoConnect());
2134 manager()->RegisterService(service);
2135 dispatcher()->DispatchPendingEvents();
2136}
2137
2138TEST_F(ManagerTest, AutoConnectOnUpdate) {
2139 MockServiceRefPtr service1 = MakeAutoConnectableService();
2140 service1->set_priority(1);
2141 MockServiceRefPtr service2 = MakeAutoConnectableService();
2142 service2->set_priority(2);
2143 manager()->RegisterService(service1);
2144 manager()->RegisterService(service2);
2145 dispatcher()->DispatchPendingEvents();
2146
2147 EXPECT_CALL(*service1.get(), AutoConnect());
2148 EXPECT_CALL(*service2.get(), state())
2149 .WillRepeatedly(Return(Service::kStateFailure));
2150 EXPECT_CALL(*service2.get(), IsFailed())
2151 .WillRepeatedly(Return(true));
2152 EXPECT_CALL(*service2.get(), IsConnected())
2153 .WillRepeatedly(Return(false));
2154 manager()->UpdateService(service2);
2155 dispatcher()->DispatchPendingEvents();
2156}
2157
2158TEST_F(ManagerTest, AutoConnectOnDeregister) {
2159 MockServiceRefPtr service1 = MakeAutoConnectableService();
2160 service1->set_priority(1);
2161 MockServiceRefPtr service2 = MakeAutoConnectableService();
2162 service2->set_priority(2);
2163 manager()->RegisterService(service1);
2164 manager()->RegisterService(service2);
2165 dispatcher()->DispatchPendingEvents();
2166
2167 EXPECT_CALL(*service1.get(), AutoConnect());
2168 manager()->DeregisterService(service2);
2169 dispatcher()->DispatchPendingEvents();
2170}
2171
Darin Petkovca621542012-07-25 14:25:56 +02002172TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2173 MockServiceRefPtr service = MakeAutoConnectableService();
2174 SetPowerState(PowerManagerProxyDelegate::kMem);
2175 SetPowerManager();
2176 EXPECT_CALL(*service, AutoConnect()).Times(0);
2177 manager()->RegisterService(service);
2178 dispatcher()->DispatchPendingEvents();
2179}
2180
2181TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2182 MockServiceRefPtr service = MakeAutoConnectableService();
2183 SetPowerState(PowerManagerProxyDelegate::kOn);
2184 SetPowerManager();
2185 EXPECT_CALL(*service, AutoConnect());
2186 manager()->RegisterService(service);
2187 dispatcher()->DispatchPendingEvents();
2188}
2189
2190TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2191 MockServiceRefPtr service = MakeAutoConnectableService();
2192 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2193 SetPowerManager();
2194 EXPECT_CALL(*service, AutoConnect());
2195 manager()->RegisterService(service);
2196 dispatcher()->DispatchPendingEvents();
2197}
2198
2199TEST_F(ManagerTest, OnPowerStateChanged) {
2200 MockServiceRefPtr service = MakeAutoConnectableService();
2201 SetPowerState(PowerManagerProxyDelegate::kOn);
2202 SetPowerManager();
2203 EXPECT_CALL(*service, AutoConnect());
2204 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002205 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002206 dispatcher()->DispatchPendingEvents();
2207
mukesh agrawal784566d2012-08-08 18:32:58 -07002208 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002209 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2210 EXPECT_CALL(*service, AutoConnect());
2211 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002212 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002213
mukesh agrawal784566d2012-08-08 18:32:58 -07002214 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002215 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2216 EXPECT_CALL(*service, AutoConnect()).Times(0);
2217 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002218 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002219}
2220
Paul Stewartc681fa02012-03-02 19:40:04 -08002221TEST_F(ManagerTest, RecheckPortal) {
2222 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
2223 .WillOnce(Return(false));
2224 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
2225 .WillOnce(Return(true));
2226 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
2227 .Times(0);
2228
2229 manager()->RegisterDevice(mock_devices_[0]);
2230 manager()->RegisterDevice(mock_devices_[1]);
2231 manager()->RegisterDevice(mock_devices_[2]);
2232
2233 manager()->RecheckPortal(NULL);
2234}
2235
Paul Stewartd215af62012-04-24 23:25:50 -07002236TEST_F(ManagerTest, RecheckPortalOnService) {
2237 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
2238 dispatcher(),
2239 metrics(),
2240 manager());
2241 EXPECT_CALL(*mock_devices_[0].get(),
2242 IsConnectedToService(IsRefPtrTo(service)))
2243 .WillOnce(Return(false));
2244 EXPECT_CALL(*mock_devices_[1].get(),
2245 IsConnectedToService(IsRefPtrTo(service)))
2246 .WillOnce(Return(true));
2247 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
2248 .WillOnce(Return(true));
2249 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
2250 .Times(0);
2251
2252 manager()->RegisterDevice(mock_devices_[0]);
2253 manager()->RegisterDevice(mock_devices_[1]);
2254 manager()->RegisterDevice(mock_devices_[2]);
2255
2256 manager()->RecheckPortalOnService(service);
2257}
2258
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002259TEST_F(ManagerTest, GetDefaultService) {
2260 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002261 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002262
2263 scoped_refptr<MockService> mock_service(
2264 new NiceMock<MockService>(control_interface(),
2265 dispatcher(),
2266 metrics(),
2267 manager()));
2268
2269 manager()->RegisterService(mock_service);
2270 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002271 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002272
2273 scoped_refptr<MockConnection> mock_connection(
2274 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002275 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002276 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002277 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002278
Paul Stewartce4ec192012-03-14 12:53:46 -07002279 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002280 manager()->DeregisterService(mock_service);
2281}
2282
Paul Stewart13ed2252012-03-21 12:52:46 -07002283TEST_F(ManagerTest, GetServiceWithGUID) {
2284 scoped_refptr<MockService> mock_service0(
2285 new NiceMock<MockService>(control_interface(),
2286 dispatcher(),
2287 metrics(),
2288 manager()));
2289
2290 scoped_refptr<MockService> mock_service1(
2291 new NiceMock<MockService>(control_interface(),
2292 dispatcher(),
2293 metrics(),
2294 manager()));
2295
Paul Stewartcb59fed2012-03-21 21:14:46 -07002296 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
2297 .Times(0);
2298 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
2299 .Times(0);
2300
Paul Stewart13ed2252012-03-21 12:52:46 -07002301 manager()->RegisterService(mock_service0);
2302 manager()->RegisterService(mock_service1);
2303
2304 const string kGUID0 = "GUID0";
2305 const string kGUID1 = "GUID1";
2306
2307 {
2308 Error error;
2309 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
2310 EXPECT_FALSE(error.IsSuccess());
2311 EXPECT_FALSE(service);
2312 }
2313
2314 KeyValueStore args;
2315 args.SetString(flimflam::kGuidProperty, kGUID1);
2316
2317 {
2318 Error error;
2319 ServiceRefPtr service = manager()->GetService(args, &error);
2320 EXPECT_EQ(Error::kInvalidArguments, error.type());
2321 EXPECT_FALSE(service);
2322 }
2323
2324 mock_service0->set_guid(kGUID0);
2325 mock_service1->set_guid(kGUID1);
2326
2327 {
2328 Error error;
2329 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
2330 EXPECT_TRUE(error.IsSuccess());
2331 EXPECT_EQ(mock_service0.get(), service.get());
2332 }
2333
2334 {
2335 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07002336 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
2337 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07002338 ServiceRefPtr service = manager()->GetService(args, &error);
2339 EXPECT_TRUE(error.IsSuccess());
2340 EXPECT_EQ(mock_service1.get(), service.get());
2341 }
2342
2343 manager()->DeregisterService(mock_service0);
2344 manager()->DeregisterService(mock_service1);
2345}
2346
Gary Morain028545d2012-04-07 14:55:52 -07002347
2348TEST_F(ManagerTest, CalculateStateOffline) {
2349 MockMetrics mock_metrics;
2350 manager()->set_metrics(&mock_metrics);
2351 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2352 .Times(AnyNumber());
2353 scoped_refptr<MockService> mock_service0(
2354 new NiceMock<MockService>(control_interface(),
2355 dispatcher(),
2356 metrics(),
2357 manager()));
2358
2359 scoped_refptr<MockService> mock_service1(
2360 new NiceMock<MockService>(control_interface(),
2361 dispatcher(),
2362 metrics(),
2363 manager()));
2364
2365 EXPECT_CALL(*mock_service0.get(), IsConnected())
2366 .WillRepeatedly(Return(false));
2367 EXPECT_CALL(*mock_service1.get(), IsConnected())
2368 .WillRepeatedly(Return(false));
2369
2370 manager()->RegisterService(mock_service0);
2371 manager()->RegisterService(mock_service1);
2372
2373 EXPECT_EQ("offline", manager()->CalculateState(NULL));
2374
2375 manager()->DeregisterService(mock_service0);
2376 manager()->DeregisterService(mock_service1);
2377}
2378
2379TEST_F(ManagerTest, CalculateStateOnline) {
2380 MockMetrics mock_metrics;
2381 manager()->set_metrics(&mock_metrics);
2382 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2383 .Times(AnyNumber());
2384 scoped_refptr<MockService> mock_service0(
2385 new NiceMock<MockService>(control_interface(),
2386 dispatcher(),
2387 metrics(),
2388 manager()));
2389
2390 scoped_refptr<MockService> mock_service1(
2391 new NiceMock<MockService>(control_interface(),
2392 dispatcher(),
2393 metrics(),
2394 manager()));
2395
2396 EXPECT_CALL(*mock_service0.get(), IsConnected())
2397 .WillRepeatedly(Return(false));
2398 EXPECT_CALL(*mock_service1.get(), IsConnected())
2399 .WillRepeatedly(Return(true));
2400 EXPECT_CALL(*mock_service0.get(), state())
2401 .WillRepeatedly(Return(Service::kStateIdle));
2402 EXPECT_CALL(*mock_service1.get(), state())
2403 .WillRepeatedly(Return(Service::kStateConnected));
2404
2405 manager()->RegisterService(mock_service0);
2406 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002407 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07002408
2409 EXPECT_EQ("online", manager()->CalculateState(NULL));
2410
2411 manager()->DeregisterService(mock_service0);
2412 manager()->DeregisterService(mock_service1);
2413}
2414
Paul Stewart10e9e4e2012-04-26 19:46:28 -07002415TEST_F(ManagerTest, StartupPortalList) {
2416 // Simulate loading value from the default profile.
2417 const string kProfileValue("wifi,vpn");
2418 manager()->props_.check_portal_list = kProfileValue;
2419
2420 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
2421 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2422 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2423
2424 const string kStartupValue("cellular,ethernet");
2425 manager()->SetStartupPortalList(kStartupValue);
2426 // Ensure profile value is not overwritten, so when we save the default
2427 // profile, the correct value will still be written.
2428 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
2429
2430 // However we should read back a different list.
2431 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
2432 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2433 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2434
2435 const string kRuntimeValue("ppp");
2436 // Setting a runtime value over the control API should overwrite both
2437 // the profile value and what we read back.
2438 Error error;
2439 manager()->mutable_store()->SetStringProperty(
2440 flimflam::kCheckPortalListProperty,
2441 kRuntimeValue,
2442 &error);
2443 ASSERT_TRUE(error.IsSuccess());
2444 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
2445 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
2446 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2447 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
2448}
2449
Paul Stewart036dba02012-08-07 12:34:41 -07002450TEST_F(ManagerTest, LinkMonitorEnabled) {
2451 const string kEnabledTechnologies("wifi,vpn");
2452 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
2453 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
2454 EXPECT_FALSE(
2455 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
2456}
2457
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002458TEST_F(ManagerTest, EnableTechnology) {
2459 Error error(Error::kOperationInitiated);
2460 ResultCallback callback;
2461 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2462 EXPECT_TRUE(error.IsSuccess());
2463
Joshua Krollda798622012-06-05 12:30:48 -07002464 ON_CALL(*mock_devices_[0], technology())
2465 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002466
2467 manager()->RegisterDevice(mock_devices_[0]);
2468
2469 // Device is enabled, so expect operation is successful.
2470 mock_devices_[0]->enabled_ = true;
2471 error.Populate(Error::kOperationInitiated);
2472 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2473 EXPECT_TRUE(error.IsSuccess());
2474
2475 // Device is disabled, so expect operation in progress.
2476 mock_devices_[0]->enabled_ = false;
2477 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
2478 error.Populate(Error::kOperationInitiated);
2479 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2480 EXPECT_TRUE(error.IsOngoing());
2481}
2482
2483TEST_F(ManagerTest, DisableTechnology) {
2484 Error error(Error::kOperationInitiated);
2485 ResultCallback callback;
2486 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2487 EXPECT_TRUE(error.IsSuccess());
2488
Joshua Krollda798622012-06-05 12:30:48 -07002489 ON_CALL(*mock_devices_[0], technology())
2490 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002491
2492 manager()->RegisterDevice(mock_devices_[0]);
2493
2494 // Device is disabled, so expect operation is successful.
2495 error.Populate(Error::kOperationInitiated);
2496 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2497 EXPECT_TRUE(error.IsSuccess());
2498
2499 // Device is enabled, so expect operation in progress.
2500 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
2501 mock_devices_[0]->enabled_ = true;
2502 error.Populate(Error::kOperationInitiated);
2503 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2504 EXPECT_TRUE(error.IsOngoing());
2505}
2506
Paul Stewart4d5efb72012-09-17 12:24:34 -07002507TEST_F(ManagerTest, IgnoredSearchList) {
2508 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
2509 SetResolver(resolver.get());
2510 vector<string> ignored_paths;
2511 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
2512 SetIgnoredDNSSearchPaths("");
2513 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
2514
2515 const string kIgnored0 = "chromium.org";
2516 ignored_paths.push_back(kIgnored0);
2517 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
2518 SetIgnoredDNSSearchPaths(kIgnored0);
2519 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
2520
2521 const string kIgnored1 = "google.com";
2522 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
2523 ignored_paths.push_back(kIgnored1);
2524 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
2525 SetIgnoredDNSSearchPaths(kIgnoredSum);
2526 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
2527
2528 SetResolver(Resolver::GetInstance());
2529}
2530
Chris Masone9be4a9d2011-05-16 15:44:09 -07002531} // namespace shill