blob: e2f5aca8808f2c3afd50db7d5a9151ebd57d0e17 [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>
Paul Stewart5ad16062013-02-21 18:10:48 -080013#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#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"
mukesh agrawal00752532013-05-03 15:46:55 -070026#include "shill/link_monitor.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070027#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070028#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080029#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070030#include "shill/mock_control.h"
Christopher Wiley1057cd72013-02-28 15:21:29 -080031#include "shill/mock_crypto_util_proxy.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070032#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080033#include "shill/mock_device_info.h"
Paul Stewart35eff132013-04-12 12:08:40 -070034#include "shill/mock_ethernet_eap_provider.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070035#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000036#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020037#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070038#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070039#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070040#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070041#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080042#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070043#include "shill/mock_wifi_service.h"
mukesh agrawal00752532013-05-03 15:46:55 -070044#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070045#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020046#include "shill/proxy_factory.h"
mukesh agrawal00752532013-05-03 15:46:55 -070047#include "shill/resolver.h"
Chris Masone6515aab2011-10-12 16:19:09 -070048#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070049#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020050#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070051
Christopher Wiley1057cd72013-02-28 15:21:29 -080052using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080053using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080054using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070055using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070056using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057using std::string;
58using std::vector;
59
Chris Masone9be4a9d2011-05-16 15:44:09 -070060namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070061using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070062using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080063using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070064using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070065using ::testing::InSequence;
mukesh agrawal784566d2012-08-08 18:32:58 -070066using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070067using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070068using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070069using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070070using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070071using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070072using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080073using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080074using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080075using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070076using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070077
Chris Masone3bd3c8c2011-06-13 08:20:26 -070078class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070079 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070080 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020081 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080082 device_info_(new NiceMock<MockDeviceInfo>(
83 control_interface(),
84 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080085 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080086 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080087 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070088 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080089 wifi_provider_(new NiceMock<MockWiFiProvider>()),
90 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
91 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070092 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 "null0",
97 "addr0",
98 0));
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 "null1",
104 "addr1",
105 1));
106 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
107 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800108 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700109 manager(),
110 "null2",
111 "addr2",
112 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800113 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
114 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800115 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800116 manager(),
117 "null3",
118 "addr3",
119 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700120 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800121 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800122
123 // Replace the manager's adaptor with a quieter one, and one
124 // we can do EXPECT*() against. Passes ownership.
125 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800126
Paul Stewart35eff132013-04-12 12:08:40 -0700127 // Replace the manager's Ethernet EAP provider with our mock.
128 // Passes ownership.
129 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
130
Paul Stewart3c504012013-01-17 17:49:58 -0800131 // Replace the manager's WiFi provider with our mock. Passes
132 // ownership.
133 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800134
135 // Replace the manager's crypto util proxy with our mock. Passes
136 // ownership.
137 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Paul Stewart9dd253e2013-04-22 08:32:59 -0700138
139 // Reset service serial number so service sorting by unique_name()
140 // (and by extension, sorting by order of creation) is predictable.
141 Service::serial_number_ = 10000;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700142 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700143 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700144
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100145 void SetMetrics(Metrics *metrics) {
146 manager()->set_metrics(metrics);
147 }
148
Paul Stewartfdd16072011-09-16 12:41:35 -0700149 bool IsDeviceRegistered(const DeviceRefPtr &device,
150 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700151 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700152 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700153 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700154 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700155 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700156
Paul Stewarta849a3d2011-11-03 05:54:09 -0700157 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
158 manager->profiles_.push_back(profile);
159 }
160
Paul Stewart63864b62012-11-07 15:10:55 -0800161 void SetRunning(bool running) {
162 manager()->running_ = running;
163 }
164
Paul Stewart75225512012-01-26 22:51:33 -0800165 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
166 return manager->ephemeral_profile_;
167 }
168
Paul Stewart307c2502013-03-23 12:32:10 -0700169 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
170 return manager->profiles_;
171 }
172
Chris Masone6515aab2011-10-12 16:19:09 -0700173 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
174 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700175 FilePath final_path(storage_path());
176 final_path = final_path.Append("test.profile");
177 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
178 storage->set_path(final_path);
179 if (!storage->Open())
180 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800181 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800182 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800183 manager,
184 id,
185 "",
186 false));
187 profile->set_storage(storage.release()); // Passes ownership of "storage".
188 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700189 }
190
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700191 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
192 const string &profile_identifier,
193 const string &service_name) {
194 GLib glib;
195 KeyFileStore store(&glib);
196 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
197 return store.Open() &&
198 store.SetString(service_name, "rather", "irrelevant") &&
199 store.Close();
200 }
201
202 Error::Type TestCreateProfile(Manager *manager, const string &name) {
203 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800204 string path;
205 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700206 return error.type();
207 }
208
209 Error::Type TestPopAnyProfile(Manager *manager) {
210 Error error;
211 manager->PopAnyProfile(&error);
212 return error.type();
213 }
214
Paul Stewart307c2502013-03-23 12:32:10 -0700215 Error::Type TestPopAllUserProfiles(Manager *manager) {
216 Error error;
217 manager->PopAllUserProfiles(&error);
218 return error.type();
219 }
220
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700221 Error::Type TestPopProfile(Manager *manager, const string &name) {
222 Error error;
223 manager->PopProfile(name, &error);
224 return error.type();
225 }
226
227 Error::Type TestPushProfile(Manager *manager, const string &name) {
228 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800229 string path;
230 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700231 return error.type();
232 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000233
Paul Stewartf3eced92013-04-17 12:18:22 -0700234 Error::Type TestInsertUserProfile(Manager *manager,
235 const string &name,
236 const string &user_hash) {
237 Error error;
238 string path;
239 manager->InsertUserProfile(name, user_hash, &path, &error);
240 return error.type();
241 }
242
Paul Stewartd2e1c362013-03-03 19:06:07 -0800243 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
244 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700245 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800246 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800247 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200248 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700249 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800250 return profile;
251 }
252
253 void AddMockProfileToManager(Manager *manager) {
254 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700255 }
256
Paul Stewartdfa46052012-06-26 09:44:14 -0700257 void CompleteServiceSort() {
258 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
259 dispatcher()->DispatchPendingEvents();
260 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
261 }
262
Paul Stewart49739c02012-08-08 17:24:03 -0700263 RpcIdentifier GetDefaultServiceRpcIdentifier() {
264 return manager()->GetDefaultServiceRpcIdentifier(NULL);
265 }
266
Paul Stewart4d5efb72012-09-17 12:24:34 -0700267 void SetResolver(Resolver *resolver) {
268 manager()->resolver_ = resolver;
269 }
270
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700271 bool SetIgnoredDNSSearchPaths(const string &search_paths, Error *error) {
272 return manager()->SetIgnoredDNSSearchPaths(search_paths, error);
273 }
274
275 bool SetCheckPortalList(const string &check_portal_list, Error *error) {
276 return manager()->SetCheckPortalList(check_portal_list, error);
Paul Stewart4d5efb72012-09-17 12:24:34 -0700277 }
278
279 const string &GetIgnoredDNSSearchPaths() {
280 return manager()->props_.ignored_dns_search_paths;
281 }
282
Paul Stewartd2e1c362013-03-03 19:06:07 -0800283 WiFiServiceRefPtr ReleaseTempMockService() {
284 // Take a reference to hold during this function.
285 WiFiServiceRefPtr temp_service = temp_mock_service_;
286 temp_mock_service_ = NULL;
287 return temp_service;
288 }
289
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700290 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000291 typedef scoped_refptr<MockService> MockServiceRefPtr;
292
Darin Petkova5e07ef2012-07-09 14:27:57 +0200293 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
294 public:
295 ServiceWatcher() {}
296 virtual ~ServiceWatcher() {}
297
298 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
299
300 private:
301 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
302 };
303
Darin Petkovca621542012-07-25 14:25:56 +0200304 class TestProxyFactory : public ProxyFactory {
305 public:
306 TestProxyFactory() {}
307
308 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
309 PowerManagerProxyDelegate */*delegate*/) {
310 return NULL;
311 }
312
313 private:
314 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
315 };
316
Darin Petkov3ec55342012-09-28 14:04:44 +0200317 class TerminationActionTest :
318 public base::SupportsWeakPtr<TerminationActionTest> {
319 public:
320 static const char kActionName[];
321
322 TerminationActionTest() : manager_(NULL) {}
323 virtual ~TerminationActionTest() {}
324
325 MOCK_METHOD1(Done, void(const Error &error));
326
327 void Action() {
328 manager_->TerminationActionComplete("action");
329 }
330
331 void set_manager(Manager *manager) { manager_ = manager; }
332
333 private:
334 Manager *manager_;
335 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
336 };
337
Christopher Wiley1057cd72013-02-28 15:21:29 -0800338 class DestinationVerificationTest :
339 public base::SupportsWeakPtr<DestinationVerificationTest> {
340 public:
341 DestinationVerificationTest() {}
342 virtual ~DestinationVerificationTest() {}
343
344 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
345 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
346 const string &value));
347 private:
348 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
349 };
350
Darin Petkovca621542012-07-25 14:25:56 +0200351 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
352 power_manager_->power_state_ = state;
353 }
354
355 void SetPowerManager() {
356 manager()->set_power_manager(power_manager_.release());
357 }
358
Darin Petkov3ec55342012-09-28 14:04:44 +0200359 HookTable *GetTerminationActions() {
360 return &manager()->termination_actions_;
361 }
362
Darin Petkovca621542012-07-25 14:25:56 +0200363 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
364 manager()->OnPowerStateChanged(state);
365 }
366
Daniel Erat0818cca2012-12-14 10:16:21 -0800367 void OnSuspendImminent(int suspend_id) {
368 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200369 }
370
Daniel Erat0818cca2012-12-14 10:16:21 -0800371 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
372 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200373 }
374
Paul Stewartbfb82552012-10-24 16:48:48 -0700375 vector<string> EnumerateAvailableServices() {
376 return manager()->EnumerateAvailableServices(NULL);
377 }
378
379 vector<string> EnumerateWatchedServices() {
380 return manager()->EnumerateWatchedServices(NULL);
381 }
382
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000383 MockServiceRefPtr MakeAutoConnectableService() {
384 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
385 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800386 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000387 manager());
388 service->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700389 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000390 return service;
391 }
392
Paul Stewart35eff132013-04-12 12:08:40 -0700393 void SetEapProviderService(const ServiceRefPtr &service) {
394 ethernet_eap_provider_->set_service(service);
395 }
396
Darin Petkovca621542012-07-25 14:25:56 +0200397 TestProxyFactory proxy_factory_;
398 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700399 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800400 scoped_ptr<MockDeviceInfo> device_info_;
401
Paul Stewartd2e1c362013-03-03 19:06:07 -0800402 // This service is held for the manager, and given ownership in a mock
403 // function. This ensures that when the Manager takes ownership, there
404 // is only one reference left.
405 scoped_refptr<MockWiFiService> temp_mock_service_;
406
Paul Stewart3c504012013-01-17 17:49:58 -0800407 // These pointers are owned by the manager, and only tracked here for
408 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800409 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700410 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800411 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800412 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700413};
414
Darin Petkov3ec55342012-09-28 14:04:44 +0200415const char ManagerTest::TerminationActionTest::kActionName[] = "action";
416
Paul Stewart22aa71b2011-09-16 12:15:11 -0700417bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700418 if (!manager()->sort_services_task_.IsCancelled()) {
419 manager()->SortServicesTask();
420 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700421 return (svc0.get() == manager()->services_[0].get() &&
422 svc1.get() == manager()->services_[1].get());
423}
424
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700425TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700426 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
427 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700428}
429
Chris Masone9be4a9d2011-05-16 15:44:09 -0700430TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700431 ON_CALL(*mock_devices_[0].get(), technology())
432 .WillByDefault(Return(Technology::kEthernet));
433 ON_CALL(*mock_devices_[1].get(), technology())
434 .WillByDefault(Return(Technology::kWifi));
435 ON_CALL(*mock_devices_[2].get(), technology())
436 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700437
Paul Stewart22aa71b2011-09-16 12:15:11 -0700438 manager()->RegisterDevice(mock_devices_[0]);
439 manager()->RegisterDevice(mock_devices_[1]);
440 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700441
Paul Stewart22aa71b2011-09-16 12:15:11 -0700442 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
443 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
444 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700445}
446
Paul Stewarta41e38d2011-11-11 07:47:29 -0800447TEST_F(ManagerTest, DeviceRegistrationAndStart) {
448 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500449 mock_devices_[0]->enabled_persistent_ = true;
450 mock_devices_[1]->enabled_persistent_ = false;
451 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800452 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500453 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800454 .Times(0);
455 manager()->RegisterDevice(mock_devices_[0]);
456 manager()->RegisterDevice(mock_devices_[1]);
457}
458
459TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800460 MockProfile *profile =
461 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800462 DeviceRefPtr device_ref(mock_devices_[0].get());
463 AdoptProfile(manager(), profile); // Passes ownership.
464 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200465 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800466 manager()->RegisterDevice(mock_devices_[0]);
467}
468
Chris Masone9be4a9d2011-05-16 15:44:09 -0700469TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700470 ON_CALL(*mock_devices_[0].get(), technology())
471 .WillByDefault(Return(Technology::kEthernet));
472 ON_CALL(*mock_devices_[1].get(), technology())
473 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700474
Gaurav Shah435de2c2011-11-17 19:01:07 -0800475 manager()->RegisterDevice(mock_devices_[0]);
476 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700477
Paul Stewart22aa71b2011-09-16 12:15:11 -0700478 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
479 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700480
Thieu Le5133b712013-02-19 14:47:21 -0800481 MockProfile *profile =
482 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700483 AdoptProfile(manager(), profile); // Passes ownership.
484
Eric Shienbrood9a245532012-03-07 14:20:39 -0500485 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700486 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800487 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700488 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700489
Eric Shienbrood9a245532012-03-07 14:20:39 -0500490 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700491 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800492 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700493 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700494}
495
496TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700497 // It's much easier and safer to use a real GLib for this test.
498 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700499 Manager manager(control_interface(),
500 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800501 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700502 &glib,
503 run_path(),
504 storage_path(),
505 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700506 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
507 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700508 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700509
Chris Masone9be4a9d2011-05-16 15:44:09 -0700510 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700511 new NiceMock<MockService>(control_interface(),
512 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800513 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700514 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700515 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700516 new NiceMock<MockService>(control_interface(),
517 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800518 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700519 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700520
Darin Petkov457728b2013-01-09 09:49:08 +0100521 string service1_name(mock_service->unique_name());
522 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700523
524 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
525 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700526 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700527 .WillRepeatedly(Return(service2_name));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700528 // TODO(quiche): make this EXPECT_CALL work (crbug.com/203247)
Chris Masone9d779932011-08-25 16:33:41 -0700529 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700530 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700531
Chris Masone9d779932011-08-25 16:33:41 -0700532 manager.RegisterService(mock_service);
533 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700534
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800535 Error error;
536 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700537 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700538 EXPECT_EQ(2, ids.size());
539 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
540 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700541
Chris Masone9d779932011-08-25 16:33:41 -0700542 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
543 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
544
545 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700546}
547
Chris Masone6515aab2011-10-12 16:19:09 -0700548TEST_F(ManagerTest, RegisterKnownService) {
549 // It's much easier and safer to use a real GLib for this test.
550 GLib glib;
551 Manager manager(control_interface(),
552 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800553 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700554 &glib,
555 run_path(),
556 storage_path(),
557 string());
558 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
559 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700560 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700561 {
562 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
563 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800564 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700565 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700566 ASSERT_TRUE(profile->AdoptService(service1));
567 ASSERT_TRUE(profile->ContainsService(service1));
568 } // Force destruction of service1.
569
570 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
571 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800572 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700573 &manager));
574 manager.RegisterService(service2);
575 EXPECT_EQ(service2->profile().get(), profile.get());
576 manager.Stop();
577}
578
579TEST_F(ManagerTest, RegisterUnknownService) {
580 // It's much easier and safer to use a real GLib for this test.
581 GLib glib;
582 Manager manager(control_interface(),
583 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800584 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700585 &glib,
586 run_path(),
587 storage_path(),
588 string());
589 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
590 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700591 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700592 {
593 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
594 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800595 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700596 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700597 ASSERT_TRUE(profile->AdoptService(service1));
598 ASSERT_TRUE(profile->ContainsService(service1));
599 } // Force destruction of service1.
600 scoped_refptr<MockService> mock_service2(
601 new NiceMock<MockService>(control_interface(),
602 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800603 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700604 &manager));
605 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100606 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700607 manager.RegisterService(mock_service2);
608 EXPECT_NE(mock_service2->profile().get(), profile.get());
609 manager.Stop();
610}
611
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000612TEST_F(ManagerTest, DeregisterUnregisteredService) {
613 // WiFi assumes that it can deregister a service that is not
614 // registered. (E.g. a hidden service can be deregistered when it
615 // loses its last endpoint, and again when WiFi is Stop()-ed.)
616 //
617 // So test that doing so doesn't cause a crash.
618 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
619 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800620 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000621 manager());
622 manager()->DeregisterService(service);
623}
624
Chris Masonea8a2c252011-06-27 22:16:30 -0700625TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700626 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700627 map<string, ::DBus::Variant> props;
628 Error error(Error::kInvalidProperty, "");
629 {
630 ::DBus::Error dbus_error;
631 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700632 manager()->mutable_store()->SetStringProperty(
633 flimflam::kCheckPortalListProperty,
634 expected,
635 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700636 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700637 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
638 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
639 expected);
640 }
641 {
642 ::DBus::Error dbus_error;
643 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700644 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
645 expected,
646 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700647 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700648 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
649 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
650 expected);
651 }
652}
653
Chris Masone3c3f6a12011-07-01 10:01:41 -0700654TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700655 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800656 manager()->RegisterDevice(mock_devices_[0]);
657 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700658 {
659 map<string, ::DBus::Variant> props;
660 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700661 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700662 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700663 vector < ::DBus::Path> devices =
664 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700665 EXPECT_EQ(2, devices.size());
666 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700667}
668
mukesh agrawal2366eed2012-03-20 18:21:50 -0700669TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700670 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700671 map<string, ::DBus::Variant> props;
672 ::DBus::Error dbus_error;
673 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
674 map<string, ::DBus::Variant>::const_iterator prop =
675 props.find(flimflam::kServicesProperty);
676 ASSERT_FALSE(prop == props.end());
677 const ::DBus::Variant &variant = prop->second;
678 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
679}
680
Chris Masone6791a432011-07-12 13:23:19 -0700681TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700682 Manager manager(control_interface(),
683 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800684 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700685 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700686 run_path(),
687 storage_path(),
688 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700689 scoped_refptr<MockService> s2(new MockService(control_interface(),
690 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800691 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700692 &manager));
693 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700694 {
Chris Masone6515aab2011-10-12 16:19:09 -0700695 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700696 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800697 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700698 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700699 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700700 .WillRepeatedly(Return(true));
701 EXPECT_CALL(*storage, Flush())
702 .Times(AnyNumber())
703 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700704 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700705 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700706 }
Chris Masone6515aab2011-10-12 16:19:09 -0700707 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800708 ProfileRefPtr profile(
709 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700710 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700711
Chris Masone6515aab2011-10-12 16:19:09 -0700712 // Now, move the Service |s2| to another profile.
713 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
714 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700715
716 // Force destruction of the original Profile, to ensure that the Service
717 // is kept alive and populated with data.
718 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700719 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700720 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700721}
722
Paul Stewart7f61e522012-03-22 11:13:45 -0700723TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
724 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800725 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700726 const string kProfileName("profile0");
727 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
728 .WillRepeatedly(Return(kProfileName));
729 AdoptProfile(manager(), mock_profile);
730
731 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
732 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
733 EXPECT_EQ(mock_profile.get(), profile.get());
734}
735
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800736TEST_F(ManagerTest, SetProfileForService) {
737 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800738 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800739 string profile_name0("profile0");
740 EXPECT_CALL(*profile0, GetRpcIdentifier())
741 .WillRepeatedly(Return(profile_name0));
742 AdoptProfile(manager(), profile0);
743 scoped_refptr<MockService> service(new MockService(control_interface(),
744 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800745 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800746 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700747 EXPECT_FALSE(manager()->HasService(service));
748 {
749 Error error;
750 EXPECT_CALL(*profile0, AdoptService(_))
751 .WillOnce(Return(true));
752 // Expect that setting the profile of a service that does not already
753 // have one assigned does not cause a crash.
754 manager()->SetProfileForService(service, "profile0", &error);
755 EXPECT_TRUE(error.IsSuccess());
756 }
757
758 // The service should be registered as a side-effect of the profile being
759 // set for this service.
760 EXPECT_TRUE(manager()->HasService(service));
761
762 // Since we have mocked Profile::AdoptServie() above, the service's
763 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800764 service->set_profile(profile0);
765
766 {
767 Error error;
768 manager()->SetProfileForService(service, "foo", &error);
769 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700770 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800771 }
772
773 {
774 Error error;
775 manager()->SetProfileForService(service, profile_name0, &error);
776 EXPECT_EQ(Error::kInvalidArguments, error.type());
777 EXPECT_EQ("Service is already connected to this profile", error.message());
778 }
779
780 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800781 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800782 string profile_name1("profile1");
783 EXPECT_CALL(*profile1, GetRpcIdentifier())
784 .WillRepeatedly(Return(profile_name1));
785 AdoptProfile(manager(), profile1);
786
787 {
788 Error error;
789 EXPECT_CALL(*profile1, AdoptService(_))
790 .WillOnce(Return(true));
791 EXPECT_CALL(*profile0, AbandonService(_))
792 .WillOnce(Return(true));
793 manager()->SetProfileForService(service, profile_name1, &error);
794 EXPECT_TRUE(error.IsSuccess());
795 }
796}
797
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700798TEST_F(ManagerTest, CreateProfile) {
799 // It's much easier to use real Glib here since we want the storage
800 // side-effects.
801 GLib glib;
802 ScopedTempDir temp_dir;
803 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
804
805 Manager manager(control_interface(),
806 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800807 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700808 &glib,
809 run_path(),
810 storage_path(),
811 temp_dir.path().value());
812
813 // Invalid name should be rejected.
814 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
815
Paul Stewartd0a3b812012-03-28 22:48:22 -0700816 // A profile with invalid characters in it should similarly be rejected.
817 EXPECT_EQ(Error::kInvalidArguments,
818 TestCreateProfile(&manager, "valid_profile"));
819
820 // We should be able to create a machine profile.
821 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700822
Gary Morainb672d352012-04-25 09:19:06 -0700823 // We should succeed in creating a valid user profile. Verify the returned
824 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700825 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700826 {
827 Error error;
828 string path;
829 manager.CreateProfile(kProfile, &path, &error);
830 EXPECT_EQ(Error::kSuccess, error.type());
831 EXPECT_EQ("/profile_rpc", path);
832 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700833
834 // We should fail in creating it a second time (already exists).
835 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
836}
837
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700838// We receive PopProfile when a user logs out, and it should always trigger a
839// MemoryLog Clear() call.
840TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
841 GLib glib;
842 ScopedTempDir temp_dir;
843 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
844 Manager manager(control_interface(),
845 dispatcher(),
846 metrics(),
847 &glib,
848 run_path(),
849 storage_path(),
850 temp_dir.path().value());
851 const char kProfile0[] = "~user/profile0";
852 const char kPurgedMessage[] = "This message should be purged";
853 // Create a profile and push it on the stack, leave one uncreated
854 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
855 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
856
857 // Popping a profile which isn't on top should still clear the log.
858 LOG(INFO) << kPurgedMessage;
859 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
860 kPurgedMessage));
861 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
862 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
863 kPurgedMessage));
864
865 // Popping an invalid profile name should do the same thing.
866 LOG(INFO) << kPurgedMessage;
867 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
868 kPurgedMessage));
869 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
870 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
871 kPurgedMessage));
872
873 // Successful pops also purge the message log.
874 LOG(INFO) << kPurgedMessage;
875 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
876 kPurgedMessage));
877 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
878 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
879 kPurgedMessage));
880}
881
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700882TEST_F(ManagerTest, PushPopProfile) {
883 // It's much easier to use real Glib in creating a Manager for this
884 // test here since we want the storage side-effects.
885 GLib glib;
886 ScopedTempDir temp_dir;
887 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
888 Manager manager(control_interface(),
889 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800890 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700891 &glib,
892 run_path(),
893 storage_path(),
894 temp_dir.path().value());
895
896 // Pushing an invalid profile should fail.
897 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
898
Paul Stewartd0a3b812012-03-28 22:48:22 -0700899 // Pushing a default profile that does not exist should fail.
900 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700901
902 const char kProfile0[] = "~user/profile0";
903 const char kProfile1[] = "~user/profile1";
904
905 // Create a couple of profiles.
906 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
907 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
908
909 // Push these profiles on the stack.
910 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
911 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
912
913 // Pushing a profile a second time should fail.
914 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
915 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
916
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800917 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700918 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800919 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700920
921 // Make sure a profile name that doesn't exist fails.
922 const char kProfile2Id[] = "profile2";
923 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
924 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
925
926 // Create a new service, with a specific storage name.
927 scoped_refptr<MockService> service(
928 new NiceMock<MockService>(control_interface(),
929 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800930 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700931 &manager));
932 const char kServiceName[] = "service_storage_name";
933 EXPECT_CALL(*service.get(), GetStorageIdentifier())
934 .WillRepeatedly(Return(kServiceName));
935 EXPECT_CALL(*service.get(), Load(_))
936 .WillRepeatedly(Return(true));
937
938 // Add this service to the manager -- it should end up in the ephemeral
939 // profile.
940 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800941 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700942
943 // Create storage for a profile that contains the service storage name.
944 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
945 kServiceName));
946
947 // When we push the profile, the service should move away from the
948 // ephemeral profile to this new profile since it has an entry for
949 // this service.
950 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800951 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700952 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
953
954 // Insert another profile that should supersede ownership of the service.
955 const char kProfile3Id[] = "profile3";
956 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
957 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
958 kServiceName));
959 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
960 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
961
962 // Popping an invalid profile name should fail.
963 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
964
965 // Popping an profile that is not at the top of the stack should fail.
966 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
967
968 // Popping the top profile should succeed.
969 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
970
971 // Moreover the service should have switched profiles to profile 2.
972 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
973
974 // Popping the top profile should succeed.
975 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
976
977 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800978 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700979
980 // Pop the remaining two services off the stack.
981 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
982 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
983
984 // Next pop should fail with "stack is empty".
985 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700986
987 const char kMachineProfile0[] = "machineprofile0";
988 const char kMachineProfile1[] = "machineprofile1";
989 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
990 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
991
992 // Should be able to push a machine profile.
993 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
994
995 // Should be able to push a user profile atop a machine profile.
996 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
997
998 // Pushing a system-wide profile on top of a user profile should fail.
999 EXPECT_EQ(Error::kInvalidArguments,
1000 TestPushProfile(&manager, kMachineProfile1));
1001
1002 // However if we pop the user profile, we should be able stack another
1003 // machine profile on.
1004 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1005 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001006
1007 // Add two user profiles to the top of the stack.
1008 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1009 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
1010 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
1011 EXPECT_EQ(4, profiles.size());
1012
1013 // PopAllUserProfiles should remove both user profiles, leaving the two
1014 // machine profiles.
1015 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1016 EXPECT_EQ(2, profiles.size());
1017 EXPECT_TRUE(profiles[0]->GetUser().empty());
1018 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001019
1020 // Use InsertUserProfile() instead. Although a machine profile is valid
1021 // in this state, it cannot be added via InsertUserProfile.
1022 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1023 EXPECT_EQ(Error::kInvalidArguments,
1024 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1025 const char kUserHash0[] = "userhash0";
1026 const char kUserHash1[] = "userhash1";
1027 EXPECT_EQ(Error::kSuccess,
1028 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1029 EXPECT_EQ(Error::kSuccess,
1030 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1031 EXPECT_EQ(3, profiles.size());
1032 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1033 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001034}
1035
Paul Stewarte73d05c2012-03-29 16:26:05 -07001036TEST_F(ManagerTest, RemoveProfile) {
1037 // It's much easier to use real Glib in creating a Manager for this
1038 // test here since we want the storage side-effects.
1039 GLib glib;
1040 ScopedTempDir temp_dir;
1041 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1042 Manager manager(control_interface(),
1043 dispatcher(),
1044 metrics(),
1045 &glib,
1046 run_path(),
1047 storage_path(),
1048 temp_dir.path().value());
1049
1050 const char kProfile0[] = "profile0";
1051 FilePath profile_path(
1052 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1053
1054 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1055 ASSERT_TRUE(file_util::PathExists(profile_path));
1056
1057 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1058
1059 // Remove should fail since the profile is still on the stack.
1060 {
1061 Error error;
1062 manager.RemoveProfile(kProfile0, &error);
1063 EXPECT_EQ(Error::kInvalidArguments, error.type());
1064 }
1065
1066 // Profile path should still exist.
1067 EXPECT_TRUE(file_util::PathExists(profile_path));
1068
1069 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1070
1071 // This should succeed now that the profile is off the stack.
1072 {
1073 Error error;
1074 manager.RemoveProfile(kProfile0, &error);
1075 EXPECT_EQ(Error::kSuccess, error.type());
1076 }
1077
1078 // Profile path should no longer exist.
1079 EXPECT_FALSE(file_util::PathExists(profile_path));
1080
1081 // Another remove succeeds, due to a foible in file_util::Delete --
1082 // it is not an error to delete a file that does not exist.
1083 {
1084 Error error;
1085 manager.RemoveProfile(kProfile0, &error);
1086 EXPECT_EQ(Error::kSuccess, error.type());
1087 }
1088
1089 // Let's create an error case that will "work". Create a non-empty
1090 // directory in the place of the profile pathname.
1091 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1092 {
1093 Error error;
1094 manager.RemoveProfile(kProfile0, &error);
1095 EXPECT_EQ(Error::kOperationFailed, error.type());
1096 }
1097}
1098
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001099TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1100 // It's much easier to use real Glib in creating a Manager for this
1101 // test here since we want the storage side-effects.
1102 GLib glib;
1103 ScopedTempDir temp_dir;
1104 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1105 Manager manager(control_interface(),
1106 dispatcher(),
1107 metrics(),
1108 &glib,
1109 run_path(),
1110 storage_path(),
1111 temp_dir.path().value());
1112
1113 const char kProfile0[] = "profile0";
1114 FilePath profile_path(
1115 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1116
1117 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1118 ASSERT_TRUE(file_util::PathExists(profile_path));
1119 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1120
1121 // Ensure that even if the backing filestore is removed, we still can't
1122 // create a profile twice.
1123 ASSERT_TRUE(file_util::Delete(profile_path, false));
1124 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1125}
1126
Paul Stewart75225512012-01-26 22:51:33 -08001127// Use this matcher instead of passing RefPtrs directly into the arguments
1128// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1129// system teardown.
1130MATCHER_P(IsRefPtrTo, ref_address, "") {
1131 return arg.get() == ref_address;
1132}
1133
1134TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1135 MockServiceRefPtr s_not_in_profile(
1136 new NiceMock<MockService>(control_interface(),
1137 dispatcher(),
1138 metrics(),
1139 manager()));
1140 MockServiceRefPtr s_not_in_group(
1141 new NiceMock<MockService>(control_interface(),
1142 dispatcher(),
1143 metrics(),
1144 manager()));
1145 MockServiceRefPtr s_configure_fail(
1146 new NiceMock<MockService>(control_interface(),
1147 dispatcher(),
1148 metrics(),
1149 manager()));
1150 MockServiceRefPtr s_configure_succeed(
1151 new NiceMock<MockService>(control_interface(),
1152 dispatcher(),
1153 metrics(),
1154 manager()));
1155
1156 string entry_name("entry_name");
1157 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1158 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1159 .WillRepeatedly(Return("not_entry_name"));
1160 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1161 .WillRepeatedly(Return(entry_name));
1162 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1163 .WillRepeatedly(Return(entry_name));
1164
1165 manager()->RegisterService(s_not_in_profile);
1166 manager()->RegisterService(s_not_in_group);
1167 manager()->RegisterService(s_configure_fail);
1168 manager()->RegisterService(s_configure_succeed);
1169
1170 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001171 new StrictMock<MockProfile>(
1172 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001173 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001174 new StrictMock<MockProfile>(
1175 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001176
1177 s_not_in_group->set_profile(profile1);
1178 s_configure_fail->set_profile(profile1);
1179 s_configure_succeed->set_profile(profile1);
1180
1181 AdoptProfile(manager(), profile0);
1182 AdoptProfile(manager(), profile1);
1183
1184 // No services are a member of this profile.
1185 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1186
1187 // No services that are members of this profile have this entry name.
1188 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1189
1190 // Only services that are members of the profile and group will be abandoned.
1191 EXPECT_CALL(*profile1.get(),
1192 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1193 EXPECT_CALL(*profile1.get(),
1194 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1195 EXPECT_CALL(*profile1.get(),
1196 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1197 .WillOnce(Return(true));
1198 EXPECT_CALL(*profile1.get(),
1199 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1200 .WillOnce(Return(true));
1201
1202 // Never allow services to re-join profile1.
1203 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1204 .WillRepeatedly(Return(false));
1205
1206 // Only allow one of the members of the profile and group to successfully
1207 // join profile0.
1208 EXPECT_CALL(*profile0.get(),
1209 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1210 EXPECT_CALL(*profile0.get(),
1211 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1212 EXPECT_CALL(*profile0.get(),
1213 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1214 .WillOnce(Return(false));
1215 EXPECT_CALL(*profile0.get(),
1216 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1217 .WillOnce(Return(true));
1218
1219 // Expect the failed-to-configure service to have Unload() called on it.
1220 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1221 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1222 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1223 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1224
1225 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1226
1227 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1228 EXPECT_EQ(profile1, s_not_in_group->profile());
1229 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1230
1231 // Since we are using a MockProfile, the profile does not actually change,
1232 // since ConfigureService was not actually called on the service.
1233 EXPECT_EQ(profile1, s_configure_succeed->profile());
1234}
1235
Paul Stewart65512e12012-03-26 18:01:08 -07001236TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1237 MockServiceRefPtr s_will_remove0(
1238 new NiceMock<MockService>(control_interface(),
1239 dispatcher(),
1240 metrics(),
1241 manager()));
1242 MockServiceRefPtr s_will_remove1(
1243 new NiceMock<MockService>(control_interface(),
1244 dispatcher(),
1245 metrics(),
1246 manager()));
1247 MockServiceRefPtr s_will_not_remove0(
1248 new NiceMock<MockService>(control_interface(),
1249 dispatcher(),
1250 metrics(),
1251 manager()));
1252 MockServiceRefPtr s_will_not_remove1(
1253 new NiceMock<MockService>(control_interface(),
1254 dispatcher(),
1255 metrics(),
1256 manager()));
1257
1258 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1259 .Times(4); // Once for each registration.
1260
1261 string entry_name("entry_name");
1262 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1263 .WillRepeatedly(Return(entry_name));
1264 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1265 .WillRepeatedly(Return(entry_name));
1266 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1267 .WillRepeatedly(Return(entry_name));
1268 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1269 .WillRepeatedly(Return(entry_name));
1270
1271 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001272 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001273 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001274 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001275 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001276 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001277 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001278 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001279
1280 // One for each service added above.
1281 ASSERT_EQ(4, manager()->services_.size());
1282
1283 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001284 new StrictMock<MockProfile>(
1285 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001286
1287 s_will_remove0->set_profile(profile);
1288 s_will_remove1->set_profile(profile);
1289 s_will_not_remove0->set_profile(profile);
1290 s_will_not_remove1->set_profile(profile);
1291
1292 AdoptProfile(manager(), profile);
1293
1294 // Deny any of the services re-entry to the profile.
1295 EXPECT_CALL(*profile, ConfigureService(_))
1296 .WillRepeatedly(Return(false));
1297
1298 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1299 .WillOnce(Return(true));
1300 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1301 .WillOnce(Return(true));
1302 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1303 .WillOnce(Return(true));
1304 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1305 .WillOnce(Return(true));
1306
1307 EXPECT_CALL(*s_will_remove0, Unload())
1308 .WillOnce(Return(true));
1309 EXPECT_CALL(*s_will_remove1, Unload())
1310 .WillOnce(Return(true));
1311 EXPECT_CALL(*s_will_not_remove0, Unload())
1312 .WillOnce(Return(false));
1313 EXPECT_CALL(*s_will_not_remove1, Unload())
1314 .WillOnce(Return(false));
1315
1316
1317 // This will cause all the profiles to be unloaded.
1318 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1319
1320 // 2 of the 4 services added above should have been unregistered and
1321 // removed, leaving 2.
1322 EXPECT_EQ(2, manager()->services_.size());
1323 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1324 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1325}
1326
1327TEST_F(ManagerTest, PopProfileWithUnload) {
1328 MockServiceRefPtr s_will_remove0(
1329 new NiceMock<MockService>(control_interface(),
1330 dispatcher(),
1331 metrics(),
1332 manager()));
1333 MockServiceRefPtr s_will_remove1(
1334 new NiceMock<MockService>(control_interface(),
1335 dispatcher(),
1336 metrics(),
1337 manager()));
1338 MockServiceRefPtr s_will_not_remove0(
1339 new NiceMock<MockService>(control_interface(),
1340 dispatcher(),
1341 metrics(),
1342 manager()));
1343 MockServiceRefPtr s_will_not_remove1(
1344 new NiceMock<MockService>(control_interface(),
1345 dispatcher(),
1346 metrics(),
1347 manager()));
1348
1349 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1350 .Times(5); // Once for each registration, and one after profile pop.
1351
1352 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001353 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001354 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001355 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001356 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001357 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001358 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001359 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001360
1361 // One for each service added above.
1362 ASSERT_EQ(4, manager()->services_.size());
1363
1364 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001365 new StrictMock<MockProfile>(
1366 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001367 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001368 new StrictMock<MockProfile>(
1369 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001370
1371 s_will_remove0->set_profile(profile1);
1372 s_will_remove1->set_profile(profile1);
1373 s_will_not_remove0->set_profile(profile1);
1374 s_will_not_remove1->set_profile(profile1);
1375
1376 AdoptProfile(manager(), profile0);
1377 AdoptProfile(manager(), profile1);
1378
1379 // Deny any of the services entry to profile0, so they will all be unloaded.
1380 EXPECT_CALL(*profile0, ConfigureService(_))
1381 .WillRepeatedly(Return(false));
1382
1383 EXPECT_CALL(*s_will_remove0, Unload())
1384 .WillOnce(Return(true));
1385 EXPECT_CALL(*s_will_remove1, Unload())
1386 .WillOnce(Return(true));
1387 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001388 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001389 EXPECT_CALL(*s_will_not_remove1, Unload())
1390 .WillOnce(Return(false));
1391
Philipp Neubeck79173602012-11-13 21:10:09 +01001392 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1393 // profile list.
1394 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1395 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1396
Paul Stewart65512e12012-03-26 18:01:08 -07001397 // This will pop profile1, which should cause all our profiles to unload.
1398 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001399 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001400
1401 // 2 of the 4 services added above should have been unregistered and
1402 // removed, leaving 2.
1403 EXPECT_EQ(2, manager()->services_.size());
1404 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1405 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001406
1407 // Expect the unloaded services to lose their profile reference.
1408 EXPECT_FALSE(s_will_remove0->profile());
1409 EXPECT_FALSE(s_will_remove1->profile());
1410
1411 // If we explicitly deregister a service, the effect should be the same
1412 // with respect to the profile reference.
1413 ASSERT_TRUE(s_will_not_remove0->profile());
1414 manager()->DeregisterService(s_will_not_remove0);
1415 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001416}
1417
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001418TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001419 {
1420 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001421 ::DBus::Variant offline_mode;
1422 offline_mode.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001423 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1424 flimflam::kOfflineModeProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001425 offline_mode,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001426 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001427 }
1428 {
1429 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001430 ::DBus::Variant country;
1431 country.writer().append_string("a_country");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001432 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1433 flimflam::kCountryProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001434 country,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001435 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001436 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001437 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001438 {
1439 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001440 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1441 flimflam::kCountryProperty,
1442 PropertyStoreTest::kBoolV,
1443 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001444 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001445 }
1446 {
1447 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001448 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1449 flimflam::kOfflineModeProperty,
1450 PropertyStoreTest::kStringV,
1451 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001452 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001453 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001454 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001455 {
1456 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001457 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001458 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001459 flimflam::kEnabledTechnologiesProperty,
1460 PropertyStoreTest::kStringsV,
1461 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001462 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001463 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001464}
1465
mukesh agrawal32399322011-09-01 10:53:43 -07001466TEST_F(ManagerTest, RequestScan) {
1467 {
1468 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001469 manager()->RegisterDevice(mock_devices_[0].get());
1470 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001471 EXPECT_CALL(*mock_devices_[0], technology())
1472 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie68d41092013-04-02 12:56:02 -07001473 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _));
Joshua Krollda798622012-06-05 12:30:48 -07001474 EXPECT_CALL(*mock_devices_[1], technology())
1475 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie68d41092013-04-02 12:56:02 -07001476 EXPECT_CALL(*mock_devices_[1], Scan(_, _)).Times(0);
1477 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001478 }
1479
1480 {
1481 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001482 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001483 EXPECT_EQ(Error::kInvalidArguments, error.type());
1484 }
1485}
1486
Darin Petkovb65c2452012-02-23 15:17:06 +01001487TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001488 KeyValueStore args;
1489 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001490 manager()->GetService(args, &e);
1491 EXPECT_EQ(Error::kInvalidArguments, e.type());
1492 EXPECT_EQ("must specify service type", e.message());
1493}
1494
1495TEST_F(ManagerTest, GetServiceUnknownType) {
1496 KeyValueStore args;
1497 Error e;
1498 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1499 manager()->GetService(args, &e);
1500 EXPECT_EQ(Error::kNotSupported, e.type());
1501 EXPECT_EQ("service type is unsupported", e.message());
1502}
1503
Paul Stewart35eff132013-04-12 12:08:40 -07001504TEST_F(ManagerTest, GetServiceEthernetEap) {
1505 KeyValueStore args;
1506 Error e;
1507 ServiceRefPtr service;
1508 args.SetString(flimflam::kTypeProperty, kTypeEthernetEap);
1509 SetEapProviderService(service);
1510 EXPECT_EQ(service, manager()->GetService(args, &e));
1511 EXPECT_TRUE(e.IsSuccess());
1512}
1513
Darin Petkovb65c2452012-02-23 15:17:06 +01001514TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001515 KeyValueStore args;
1516 Error e;
1517 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001518 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001519 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001520 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001521 manager()->GetService(args, &e);
1522 EXPECT_TRUE(e.IsSuccess());
1523}
1524
Darin Petkov33af05c2012-02-28 10:10:30 +01001525TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1526 KeyValueStore args;
1527 Error e;
1528 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001529 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001530 new StrictMock<MockProfile>(
1531 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001532 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001533 ServiceRefPtr service = manager()->GetService(args, &e);
1534 EXPECT_EQ(Error::kNotSupported, e.type());
1535 EXPECT_FALSE(service);
1536}
1537
Darin Petkovb65c2452012-02-23 15:17:06 +01001538TEST_F(ManagerTest, GetServiceVPN) {
1539 KeyValueStore args;
1540 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001541 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001542 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001543 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001544 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001545 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001546 new StrictMock<MockProfile>(
1547 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001548 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001549
1550#if defined(DISABLE_VPN)
1551
1552 ServiceRefPtr service = manager()->GetService(args, &e);
1553 EXPECT_EQ(Error::kNotSupported, e.type());
1554 EXPECT_FALSE(service);
1555
1556#else
1557
Paul Stewart7f5ad572012-06-04 15:18:54 -07001558 ServiceRefPtr updated_service;
1559 EXPECT_CALL(*profile, UpdateService(_))
1560 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1561 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001562 EXPECT_CALL(*profile, LoadService(_))
1563 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001564 EXPECT_CALL(*profile, ConfigureService(_))
1565 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001566 ServiceRefPtr service = manager()->GetService(args, &e);
1567 EXPECT_TRUE(e.IsSuccess());
1568 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001569 EXPECT_EQ(service, updated_service);
1570 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001571
1572#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001573}
1574
Darin Petkovc63dcf02012-05-24 11:51:43 +02001575TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1576 KeyValueStore args;
1577 Error e;
1578 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1579 ServiceRefPtr service = manager()->GetService(args, &e);
1580 EXPECT_EQ(Error::kInvalidArguments, e.type());
1581 EXPECT_EQ("Missing WiMAX network id.", e.message());
1582 EXPECT_FALSE(service);
1583}
1584
Darin Petkovd1cd7972012-05-22 15:26:15 +02001585TEST_F(ManagerTest, GetServiceWiMax) {
1586 KeyValueStore args;
1587 Error e;
1588 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001589 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1590 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1591 ServiceRefPtr service = manager()->GetService(args, &e);
1592 EXPECT_TRUE(e.IsSuccess());
1593 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001594}
1595
Paul Stewart7f61e522012-03-22 11:13:45 -07001596TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1597 // Manager calls ActiveProfile() so we need at least one profile installed.
1598 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001599 new NiceMock<MockProfile>(
1600 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001601 AdoptProfile(manager(), profile);
1602
1603 KeyValueStore args;
1604 args.SetString(flimflam::kProfileProperty, "xxx");
1605 Error error;
1606 manager()->ConfigureService(args, &error);
1607 EXPECT_EQ(Error::kInvalidArguments, error.type());
1608 EXPECT_EQ("Invalid profile name xxx", error.message());
1609}
1610
1611TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1612 // Manager calls ActiveProfile() so we need at least one profile installed.
1613 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001614 new NiceMock<MockProfile>(
1615 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001616 AdoptProfile(manager(), profile);
1617
1618 KeyValueStore args;
1619 Error error;
1620 manager()->ConfigureService(args, &error);
1621 EXPECT_EQ(Error::kInvalidArguments, error.type());
1622 EXPECT_EQ("must specify service type", error.message());
1623}
1624
1625// A registered service in the ephemeral profile should be moved to the
1626// active profile as a part of configuration if no profile was explicitly
1627// specified.
1628TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1629 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001630 new NiceMock<MockProfile>(
1631 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001632
1633 AdoptProfile(manager(), profile); // This is now the active profile.
1634
Paul Stewartd2e1c362013-03-03 19:06:07 -08001635 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001636 scoped_refptr<MockWiFiService> service(
1637 new NiceMock<MockWiFiService>(control_interface(),
1638 dispatcher(),
1639 metrics(),
1640 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001641 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001642 ssid,
1643 "",
1644 "",
1645 false));
1646
1647 manager()->RegisterService(service);
1648 service->set_profile(GetEphemeralProfile(manager()));
1649
Paul Stewart3c504012013-01-17 17:49:58 -08001650 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001651 .WillOnce(Return(service));
1652 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1653 .WillOnce(Return(true));
1654 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1655 .WillOnce(Return(true));
1656
1657 KeyValueStore args;
1658 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1659 Error error;
1660 manager()->ConfigureService(args, &error);
1661 EXPECT_TRUE(error.IsSuccess());
1662}
1663
Paul Stewart2c575d22012-12-07 12:28:57 -08001664// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001665// specify a profile, it should be moved from the profile it was previously
1666// in to the specified profile if one was requested.
1667TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1668 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001669 new NiceMock<MockProfile>(
1670 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001671 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001672 new NiceMock<MockProfile>(
1673 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001674
1675 const string kProfileName0 = "profile0";
1676 const string kProfileName1 = "profile1";
1677
1678 EXPECT_CALL(*profile0, GetRpcIdentifier())
1679 .WillRepeatedly(Return(kProfileName0));
1680 EXPECT_CALL(*profile1, GetRpcIdentifier())
1681 .WillRepeatedly(Return(kProfileName1));
1682
1683 AdoptProfile(manager(), profile0);
1684 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1685
Paul Stewartd2e1c362013-03-03 19:06:07 -08001686 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001687 scoped_refptr<MockWiFiService> service(
1688 new NiceMock<MockWiFiService>(control_interface(),
1689 dispatcher(),
1690 metrics(),
1691 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001692 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001693 ssid,
1694 "",
1695 "",
1696 false));
1697
1698 manager()->RegisterService(service);
1699 service->set_profile(profile1);
1700
Paul Stewart3c504012013-01-17 17:49:58 -08001701 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001702 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001703 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1704 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001705 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1706 .WillOnce(Return(true));
1707 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1708 .WillOnce(Return(true));
1709 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1710 .WillOnce(Return(true));
1711
1712 KeyValueStore args;
1713 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1714 args.SetString(flimflam::kProfileProperty, kProfileName0);
1715 Error error;
1716 manager()->ConfigureService(args, &error);
1717 EXPECT_TRUE(error.IsSuccess());
1718 service->set_profile(NULL); // Breaks refcounting loop.
1719}
1720
Paul Stewart2c575d22012-12-07 12:28:57 -08001721// If we configure a service that is already a member of the specified
1722// profile, the Manager should not call LoadService or AdoptService again
1723// on this service.
1724TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1725 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001726 new NiceMock<MockProfile>(
1727 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001728
1729 const string kProfileName0 = "profile0";
1730
1731 EXPECT_CALL(*profile0, GetRpcIdentifier())
1732 .WillRepeatedly(Return(kProfileName0));
1733
1734 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1735
Paul Stewartd2e1c362013-03-03 19:06:07 -08001736 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001737 scoped_refptr<MockWiFiService> service(
1738 new NiceMock<MockWiFiService>(control_interface(),
1739 dispatcher(),
1740 metrics(),
1741 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001742 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001743 ssid,
1744 "",
1745 "",
1746 false));
1747
1748 manager()->RegisterService(service);
1749 service->set_profile(profile0);
1750
Paul Stewart3c504012013-01-17 17:49:58 -08001751 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001752 .WillOnce(Return(service));
1753 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1754 .Times(0);
1755 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1756 .WillOnce(Return(true));
1757 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1758 .Times(0);
1759
1760 KeyValueStore args;
1761 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1762 args.SetString(flimflam::kProfileProperty, kProfileName0);
1763 Error error;
1764 manager()->ConfigureService(args, &error);
1765 EXPECT_TRUE(error.IsSuccess());
1766 service->set_profile(NULL); // Breaks refcounting loop.
1767}
1768
Paul Stewart7f61e522012-03-22 11:13:45 -07001769// An unregistered service should remain unregistered, but its contents should
1770// be saved to the specified profile nonetheless.
1771TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1772 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001773 new NiceMock<MockProfile>(
1774 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001775 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001776 new NiceMock<MockProfile>(
1777 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001778
1779 const string kProfileName0 = "profile0";
1780 const string kProfileName1 = "profile1";
1781
1782 EXPECT_CALL(*profile0, GetRpcIdentifier())
1783 .WillRepeatedly(Return(kProfileName0));
1784 EXPECT_CALL(*profile1, GetRpcIdentifier())
1785 .WillRepeatedly(Return(kProfileName1));
1786
1787 AdoptProfile(manager(), profile0);
1788 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1789
Paul Stewartd2e1c362013-03-03 19:06:07 -08001790 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001791 scoped_refptr<MockWiFiService> service(
1792 new NiceMock<MockWiFiService>(control_interface(),
1793 dispatcher(),
1794 metrics(),
1795 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001796 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001797 ssid,
1798 "",
1799 "",
1800 false));
1801
1802 service->set_profile(profile1);
1803
Paul Stewart3c504012013-01-17 17:49:58 -08001804 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001805 .WillOnce(Return(service));
1806 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1807 .WillOnce(Return(true));
1808 EXPECT_CALL(*profile0, AdoptService(_))
1809 .Times(0);
1810 EXPECT_CALL(*profile1, AdoptService(_))
1811 .Times(0);
1812
1813 KeyValueStore args;
1814 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1815 args.SetString(flimflam::kProfileProperty, kProfileName0);
1816 Error error;
1817 manager()->ConfigureService(args, &error);
1818 EXPECT_TRUE(error.IsSuccess());
1819}
1820
Paul Stewartd2e1c362013-03-03 19:06:07 -08001821TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1822 KeyValueStore args;
1823 Error error;
1824 ServiceRefPtr service =
1825 manager()->ConfigureServiceForProfile("", args, &error);
1826 EXPECT_EQ(Error::kNotSupported, error.type());
1827 EXPECT_EQ("This method only supports WiFi services", error.message());
1828 EXPECT_EQ(NULL, service.get());
1829}
1830
1831TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1832 KeyValueStore args;
1833 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1834 Error error;
1835 ServiceRefPtr service =
1836 manager()->ConfigureServiceForProfile("", args, &error);
1837 EXPECT_EQ(Error::kNotSupported, error.type());
1838 EXPECT_EQ("This method only supports WiFi services", error.message());
1839 EXPECT_EQ(NULL, service.get());
1840}
1841
1842TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1843 KeyValueStore args;
1844 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1845 Error error;
1846 ServiceRefPtr service =
1847 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1848 EXPECT_EQ(Error::kNotFound, error.type());
1849 EXPECT_EQ("Profile specified was not found", error.message());
1850 EXPECT_EQ(NULL, service.get());
1851}
1852
1853TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1854 const string kProfileName0 = "profile0";
1855 const string kProfileName1 = "profile1";
1856 scoped_refptr<MockProfile> profile0(
1857 AddNamedMockProfileToManager(manager(), kProfileName0));
1858
1859 KeyValueStore args;
1860 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1861 args.SetString(flimflam::kProfileProperty, kProfileName1);
1862 Error error;
1863 ServiceRefPtr service =
1864 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1865 EXPECT_EQ(Error::kInvalidArguments, error.type());
1866 EXPECT_EQ("Profile argument does not match that in "
1867 "the configuration arguments", error.message());
1868 EXPECT_EQ(NULL, service.get());
1869}
1870
1871TEST_F(ManagerTest,
1872 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1873 const string kProfileName0 = "profile0";
1874 scoped_refptr<MockProfile> profile0(
1875 AddNamedMockProfileToManager(manager(), kProfileName0));
1876 KeyValueStore args;
1877 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1878 args.SetString(flimflam::kProfileProperty, kProfileName0);
1879
1880 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1881 .WillOnce(Return(WiFiServiceRefPtr()));
1882 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1883 .WillOnce(Return(WiFiServiceRefPtr()));
1884 Error error;
1885 ServiceRefPtr service =
1886 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1887 // Since we didn't set the error in the GetService expectation above...
1888 EXPECT_TRUE(error.IsSuccess());
1889 EXPECT_EQ(NULL, service.get());
1890}
1891
1892TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1893 const string kProfileName0 = "profile0";
1894 scoped_refptr<MockProfile> profile0(
1895 AddNamedMockProfileToManager(manager(), kProfileName0));
1896
1897 KeyValueStore args;
1898 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1899
1900 scoped_refptr<MockWiFiService> mock_service(
1901 new NiceMock<MockWiFiService>(control_interface(),
1902 dispatcher(),
1903 metrics(),
1904 manager(),
1905 wifi_provider_,
1906 vector<uint8_t>(),
1907 flimflam::kModeManaged,
1908 flimflam::kSecurityNone,
1909 false));
1910 ServiceRefPtr mock_service_generic(mock_service.get());
1911 mock_service->set_profile(profile0);
1912 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1913 .WillOnce(Return(WiFiServiceRefPtr()));
1914 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1915 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1916 .WillOnce(Return(true));
1917 Error error;
1918 ServiceRefPtr service =
1919 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1920 EXPECT_TRUE(error.IsSuccess());
1921 EXPECT_EQ(mock_service.get(), service.get());
1922 mock_service->set_profile(NULL); // Breaks reference cycle.
1923}
1924
1925TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
1926 scoped_refptr<MockService> mock_service(
1927 new NiceMock<MockService>(control_interface(),
1928 dispatcher(),
1929 metrics(),
1930 manager()));
1931 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001932 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08001933 manager()->RegisterService(mock_service);
1934 ServiceRefPtr mock_service_generic(mock_service.get());
1935
1936 const string kProfileName = "profile";
1937 scoped_refptr<MockProfile> profile(
1938 AddNamedMockProfileToManager(manager(), kProfileName));
1939 mock_service->set_profile(profile);
1940
1941 EXPECT_CALL(*mock_service, technology())
1942 .WillOnce(Return(Technology::kCellular))
1943 .WillOnce(Return(Technology::kWifi));
1944
1945 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
1946 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1947 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1948
1949 KeyValueStore args;
1950 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1951 args.SetString(flimflam::kGuidProperty, kGUID);
1952
1953 // The first attempt should fail because the service reports a technology
1954 // other than "WiFi".
1955 {
1956 Error error;
1957 ServiceRefPtr service =
1958 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1959 EXPECT_EQ(NULL, service.get());
1960 EXPECT_EQ(Error::kNotSupported, error.type());
1961 EXPECT_EQ("This GUID matches a non-WiFi service", error.message());
1962 }
1963
1964 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1965 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1966
1967 {
1968 Error error;
1969 ServiceRefPtr service =
1970 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1971 EXPECT_TRUE(error.IsSuccess());
1972 EXPECT_EQ(mock_service.get(), service.get());
1973 EXPECT_EQ(profile.get(), service->profile().get());
1974 }
1975 mock_service->set_profile(NULL); // Breaks reference cycle.
1976}
1977
1978TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
1979 const string kProfileName = "profile";
1980 scoped_refptr<MockProfile> profile(
1981 AddNamedMockProfileToManager(manager(), kProfileName));
1982
1983 scoped_refptr<MockWiFiService> mock_service(
1984 new NiceMock<MockWiFiService>(control_interface(),
1985 dispatcher(),
1986 metrics(),
1987 manager(),
1988 wifi_provider_,
1989 vector<uint8_t>(),
1990 flimflam::kModeManaged,
1991 flimflam::kSecurityNone,
1992 false));
1993 mock_service->set_profile(profile);
1994 ServiceRefPtr mock_service_generic(mock_service.get());
1995
1996 KeyValueStore args;
1997 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1998 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1999 .WillOnce(Return(mock_service));
2000 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2001 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2002 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2003 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2004
2005 Error error;
2006 ServiceRefPtr service =
2007 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2008 EXPECT_TRUE(error.IsSuccess());
2009 EXPECT_EQ(mock_service.get(), service.get());
2010 EXPECT_EQ(profile.get(), service->profile().get());
2011 mock_service->set_profile(NULL); // Breaks reference cycle.
2012}
2013
2014TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2015 const string kProfileName = "profile";
2016 scoped_refptr<MockProfile> profile(
2017 AddNamedMockProfileToManager(manager(), kProfileName));
2018
2019 scoped_refptr<MockWiFiService> mock_service(
2020 new NiceMock<MockWiFiService>(control_interface(),
2021 dispatcher(),
2022 metrics(),
2023 manager(),
2024 wifi_provider_,
2025 vector<uint8_t>(),
2026 flimflam::kModeManaged,
2027 flimflam::kSecurityNone,
2028 false));
2029 mock_service->set_profile(GetEphemeralProfile(manager()));
2030 ServiceRefPtr mock_service_generic(mock_service.get());
2031
2032 KeyValueStore args;
2033 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2034 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2035 .WillOnce(Return(mock_service));
2036 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2037 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2038 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2039
2040 Error error;
2041 ServiceRefPtr service =
2042 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2043 EXPECT_TRUE(error.IsSuccess());
2044 EXPECT_EQ(mock_service.get(), service.get());
2045 EXPECT_EQ(profile.get(), service->profile().get());
2046 mock_service->set_profile(NULL); // Breaks reference cycle.
2047}
2048
2049TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2050 const string kProfileName0 = "profile0";
2051 scoped_refptr<MockProfile> profile0(
2052 AddNamedMockProfileToManager(manager(), kProfileName0));
2053 const string kProfileName1 = "profile1";
2054 scoped_refptr<MockProfile> profile1(
2055 AddNamedMockProfileToManager(manager(), kProfileName1));
2056
2057 scoped_refptr<MockWiFiService> mock_service(
2058 new NiceMock<MockWiFiService>(control_interface(),
2059 dispatcher(),
2060 metrics(),
2061 manager(),
2062 wifi_provider_,
2063 vector<uint8_t>(),
2064 flimflam::kModeManaged,
2065 flimflam::kSecurityNone,
2066 false));
2067 manager()->RegisterService(mock_service);
2068 mock_service->set_profile(profile0);
2069 ServiceRefPtr mock_service_generic(mock_service.get());
2070
2071 KeyValueStore args;
2072 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2073 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2074 .WillOnce(Return(mock_service));
2075 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2076 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2077 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2078 // This happens once to make the service loadable for the ConfigureService
2079 // below, and a second time after the service is modified.
2080 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2081 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2082 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2083 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2084
2085 Error error;
2086 ServiceRefPtr service =
2087 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2088 EXPECT_TRUE(error.IsSuccess());
2089 EXPECT_EQ(mock_service.get(), service.get());
2090 mock_service->set_profile(NULL); // Breaks reference cycle.
2091}
2092
2093TEST_F(ManagerTest,
2094 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2095 const string kProfileName0 = "profile0";
2096 scoped_refptr<MockProfile> profile0(
2097 AddNamedMockProfileToManager(manager(), kProfileName0));
2098 const string kProfileName1 = "profile1";
2099 scoped_refptr<MockProfile> profile1(
2100 AddNamedMockProfileToManager(manager(), kProfileName1));
2101
2102 scoped_refptr<MockWiFiService> matching_service(
2103 new StrictMock<MockWiFiService>(control_interface(),
2104 dispatcher(),
2105 metrics(),
2106 manager(),
2107 wifi_provider_,
2108 vector<uint8_t>(),
2109 flimflam::kModeManaged,
2110 flimflam::kSecurityNone,
2111 false));
2112 matching_service->set_profile(profile1);
2113
2114 // We need to get rid of our reference to this mock service as soon
2115 // as Manager::ConfigureServiceForProfile() takes a reference in its
2116 // call to WiFiProvider::CreateTemporaryService(). This way the
2117 // latter function can keep a DCHECK(service->HasOneRef() even in
2118 // unit tests.
2119 temp_mock_service_ =
2120 new NiceMock<MockWiFiService>(control_interface(),
2121 dispatcher(),
2122 metrics(),
2123 manager(),
2124 wifi_provider_,
2125 vector<uint8_t>(),
2126 flimflam::kModeManaged,
2127 flimflam::kSecurityNone,
2128 false);
2129
2130 // Only hold a pointer here so we don't affect the refcount.
2131 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2132
2133 KeyValueStore args;
2134 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2135 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2136 .WillOnce(Return(matching_service));
2137 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2138 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2139 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2140 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2141 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2142 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2143 .Times(1);
2144 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2145 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2146
2147 Error error;
2148 ServiceRefPtr service =
2149 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2150 EXPECT_TRUE(error.IsSuccess());
2151 EXPECT_EQ(NULL, service.get());
2152 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2153}
2154
Paul Stewart7a20aa42013-01-17 12:21:41 -08002155TEST_F(ManagerTest, FindMatchingService) {
2156 KeyValueStore args;
2157 {
2158 Error error;
2159 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2160 EXPECT_EQ(Error::kNotFound, error.type());
2161 }
2162
2163 scoped_refptr<MockService> mock_service0(
2164 new NiceMock<MockService>(control_interface(),
2165 dispatcher(),
2166 metrics(),
2167 manager()));
2168 scoped_refptr<MockService> mock_service1(
2169 new NiceMock<MockService>(control_interface(),
2170 dispatcher(),
2171 metrics(),
2172 manager()));
2173 manager()->RegisterService(mock_service0);
2174 manager()->RegisterService(mock_service1);
2175 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2176 .WillOnce(Return(true))
2177 .WillRepeatedly(Return(false));
2178 {
2179 Error error;
2180 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2181 EXPECT_TRUE(error.IsSuccess());
2182 }
2183 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2184 .WillOnce(Return(true))
2185 .WillRepeatedly(Return(false));
2186 {
2187 Error error;
2188 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2189 EXPECT_TRUE(error.IsSuccess());
2190 }
2191 {
2192 Error error;
2193 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2194 EXPECT_EQ(Error::kNotFound, error.type());
2195 }
2196}
2197
Paul Stewart22aa71b2011-09-16 12:15:11 -07002198TEST_F(ManagerTest, TechnologyOrder) {
2199 Error error;
2200 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2201 string(flimflam::kTypeWifi), &error);
2202 ASSERT_TRUE(error.IsSuccess());
2203 EXPECT_EQ(manager()->GetTechnologyOrder(),
2204 string(flimflam::kTypeEthernet) + "," +
2205 string(flimflam::kTypeWifi));
2206
2207 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2208 string(flimflam::kTypeWifi), &error);
2209 ASSERT_FALSE(error.IsSuccess());
2210 EXPECT_EQ(Error::kInvalidArguments, error.type());
2211 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2212 string(flimflam::kTypeWifi),
2213 manager()->GetTechnologyOrder());
2214}
2215
2216TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002217 // TODO(quiche): Some of these tests would probably fit better in
2218 // service_unittest, since the actual comparison of Services is
Paul Stewartee6b3d72013-07-12 16:07:51 -07002219 // implemented in Service. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002220
Paul Stewart22aa71b2011-09-16 12:15:11 -07002221 scoped_refptr<MockService> mock_service0(
2222 new NiceMock<MockService>(control_interface(),
2223 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002224 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002225 manager()));
2226 scoped_refptr<MockService> mock_service1(
2227 new NiceMock<MockService>(control_interface(),
2228 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002229 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002230 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002231
2232 manager()->RegisterService(mock_service0);
2233 manager()->RegisterService(mock_service1);
2234
Darin Petkov457728b2013-01-09 09:49:08 +01002235 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002236 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2237
2238 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002239 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002240 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2241
2242 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002243 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002244 manager()->UpdateService(mock_service1);
2245 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2246
2247 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002248 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002249 manager()->UpdateService(mock_service0);
2250 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2251
2252 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002253 EXPECT_CALL(*mock_service0.get(), technology())
2254 .WillRepeatedly(Return((Technology::kWifi)));
2255 EXPECT_CALL(*mock_service1.get(), technology())
2256 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002257
2258 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002259 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002260 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002261 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2262
2263 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2264 string(flimflam::kTypeEthernet), &error);
2265 EXPECT_TRUE(error.IsSuccess());
2266 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2267
Gaurav Shah435de2c2011-11-17 19:01:07 -08002268 // Priority.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002269 mock_service0->SetPriority(1, NULL);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002270 manager()->UpdateService(mock_service0);
2271 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2272
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002273 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002274 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002275 manager()->UpdateService(mock_service1);
2276 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2277
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002278 // Auto-connect.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002279 mock_service0->SetAutoConnect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002280 manager()->UpdateService(mock_service0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002281 mock_service1->SetAutoConnect(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002282 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002283 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2284
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002285 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2286 // to any of the others below, so we reset to the default state after
2287 // testing.
2288 EXPECT_CALL(*mock_service1.get(),
2289 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2290 .WillOnce(Return(true))
2291 .WillRepeatedly(Return(false));
2292 manager()->UpdateService(mock_service1);
2293 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2294 manager()->UpdateService(mock_service0);
2295 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2296
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002297 // Connectable.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002298 mock_service1->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002299 manager()->UpdateService(mock_service1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002300 mock_service0->SetConnectable(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002301 manager()->UpdateService(mock_service0);
2302 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2303
2304 // IsFailed.
2305 EXPECT_CALL(*mock_service0.get(), state())
2306 .WillRepeatedly(Return(Service::kStateIdle));
2307 EXPECT_CALL(*mock_service0.get(), IsFailed())
2308 .WillRepeatedly(Return(false));
2309 manager()->UpdateService(mock_service0);
2310 EXPECT_CALL(*mock_service0.get(), state())
2311 .WillRepeatedly(Return(Service::kStateFailure));
2312 EXPECT_CALL(*mock_service1.get(), IsFailed())
2313 .WillRepeatedly(Return(true));
2314 manager()->UpdateService(mock_service1);
2315 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2316
2317 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002318 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002319 .WillRepeatedly(Return(Service::kStateAssociating));
2320 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002321 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002322 manager()->UpdateService(mock_service1);
2323 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2324
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002325 // Connected.
2326 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002327 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002328 EXPECT_CALL(*mock_service0.get(), IsConnected())
2329 .WillRepeatedly(Return(true));
2330 manager()->UpdateService(mock_service0);
2331 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2332
Paul Stewarta121c442012-06-09 14:12:58 -07002333 // Portal.
2334 EXPECT_CALL(*mock_service1.get(), state())
2335 .WillRepeatedly(Return(Service::kStateConnected));
2336 EXPECT_CALL(*mock_service1.get(), IsConnected())
2337 .WillRepeatedly(Return(true));
2338 manager()->UpdateService(mock_service1);
2339 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2340
Paul Stewart22aa71b2011-09-16 12:15:11 -07002341 manager()->DeregisterService(mock_service0);
2342 manager()->DeregisterService(mock_service1);
2343}
2344
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002345TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002346 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002347 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002348
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002349 scoped_refptr<MockService> mock_service0(
2350 new NiceMock<MockService>(control_interface(),
2351 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002352 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002353 manager()));
2354 scoped_refptr<MockService> mock_service1(
2355 new NiceMock<MockService>(control_interface(),
2356 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002357 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002358 manager()));
2359
2360 scoped_refptr<MockConnection> mock_connection0(
2361 new NiceMock<MockConnection>(device_info_.get()));
2362 scoped_refptr<MockConnection> mock_connection1(
2363 new NiceMock<MockConnection>(device_info_.get()));
2364
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002365 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002366 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002367 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002368 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002369 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002370 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002371
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002372 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002373 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002374
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002375 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002376 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002377 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002378
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002379 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002380 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002381 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002382
Paul Stewartce4ec192012-03-14 12:53:46 -07002383 mock_service0->set_mock_connection(mock_connection0);
2384 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002385
2386 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002387 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002388 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002389
Darin Petkova5e07ef2012-07-09 14:27:57 +02002390 ServiceWatcher service_watcher;
2391 int tag =
2392 manager()->RegisterDefaultServiceCallback(
2393 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2394 service_watcher.AsWeakPtr()));
2395 EXPECT_EQ(1, tag);
2396
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002397 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002398 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2399 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002400 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002401 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002402 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002403
Darin Petkova5e07ef2012-07-09 14:27:57 +02002404 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002405 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002406 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002407 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002408 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002409 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002410 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002411
Paul Stewartce4ec192012-03-14 12:53:46 -07002412 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002413 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002414 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002415 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002416
2417 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002418 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002419}
2420
Darin Petkova5e07ef2012-07-09 14:27:57 +02002421TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2422 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2423 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2424
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002425 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002426 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002427
2428 scoped_refptr<MockService> mock_service(
2429 new NiceMock<MockService>(
2430 control_interface(), dispatcher(), metrics(), manager()));
2431 ServiceRefPtr service = mock_service;
2432 ServiceRefPtr null_service;
2433
2434 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2435 manager()->NotifyDefaultServiceChanged(null_service);
2436
2437 ServiceWatcher service_watcher1;
2438 ServiceWatcher service_watcher2;
2439 int tag1 =
2440 manager()->RegisterDefaultServiceCallback(
2441 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2442 service_watcher1.AsWeakPtr()));
2443 EXPECT_EQ(1, tag1);
2444 int tag2 =
2445 manager()->RegisterDefaultServiceCallback(
2446 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2447 service_watcher2.AsWeakPtr()));
2448 EXPECT_EQ(2, tag2);
2449
2450 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2451 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2452 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2453 manager()->NotifyDefaultServiceChanged(null_service);
2454
2455 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2456 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2457 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2458 manager()->NotifyDefaultServiceChanged(mock_service);
2459
2460 manager()->DeregisterDefaultServiceCallback(tag1);
2461 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2462 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2463 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2464 manager()->NotifyDefaultServiceChanged(mock_service);
2465 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2466
2467 manager()->DeregisterDefaultServiceCallback(tag2);
2468 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2469 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2470 manager()->NotifyDefaultServiceChanged(mock_service);
2471
2472 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2473 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2474}
2475
Gaurav Shah435de2c2011-11-17 19:01:07 -08002476TEST_F(ManagerTest, AvailableTechnologies) {
2477 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2478 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002479 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002480 manager(),
2481 "null4",
2482 "addr4",
2483 0));
2484 manager()->RegisterDevice(mock_devices_[0]);
2485 manager()->RegisterDevice(mock_devices_[1]);
2486 manager()->RegisterDevice(mock_devices_[2]);
2487 manager()->RegisterDevice(mock_devices_[3]);
2488
2489 ON_CALL(*mock_devices_[0].get(), technology())
2490 .WillByDefault(Return(Technology::kEthernet));
2491 ON_CALL(*mock_devices_[1].get(), technology())
2492 .WillByDefault(Return(Technology::kWifi));
2493 ON_CALL(*mock_devices_[2].get(), technology())
2494 .WillByDefault(Return(Technology::kCellular));
2495 ON_CALL(*mock_devices_[3].get(), technology())
2496 .WillByDefault(Return(Technology::kWifi));
2497
2498 set<string> expected_technologies;
2499 expected_technologies.insert(Technology::NameFromIdentifier(
2500 Technology::kEthernet));
2501 expected_technologies.insert(Technology::NameFromIdentifier(
2502 Technology::kWifi));
2503 expected_technologies.insert(Technology::NameFromIdentifier(
2504 Technology::kCellular));
2505 Error error;
2506 vector<string> technologies = manager()->AvailableTechnologies(&error);
2507
2508 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2509 ContainerEq(expected_technologies));
2510}
2511
2512TEST_F(ManagerTest, ConnectedTechnologies) {
2513 scoped_refptr<MockService> connected_service1(
2514 new NiceMock<MockService>(control_interface(),
2515 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002516 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002517 manager()));
2518 scoped_refptr<MockService> connected_service2(
2519 new NiceMock<MockService>(control_interface(),
2520 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002521 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002522 manager()));
2523 scoped_refptr<MockService> disconnected_service1(
2524 new NiceMock<MockService>(control_interface(),
2525 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002526 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002527 manager()));
2528 scoped_refptr<MockService> disconnected_service2(
2529 new NiceMock<MockService>(control_interface(),
2530 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002531 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002532 manager()));
2533
2534 ON_CALL(*connected_service1.get(), IsConnected())
2535 .WillByDefault(Return(true));
2536 ON_CALL(*connected_service2.get(), IsConnected())
2537 .WillByDefault(Return(true));
2538
2539 manager()->RegisterService(connected_service1);
2540 manager()->RegisterService(connected_service2);
2541 manager()->RegisterService(disconnected_service1);
2542 manager()->RegisterService(disconnected_service2);
2543
2544 manager()->RegisterDevice(mock_devices_[0]);
2545 manager()->RegisterDevice(mock_devices_[1]);
2546 manager()->RegisterDevice(mock_devices_[2]);
2547 manager()->RegisterDevice(mock_devices_[3]);
2548
2549 ON_CALL(*mock_devices_[0].get(), technology())
2550 .WillByDefault(Return(Technology::kEthernet));
2551 ON_CALL(*mock_devices_[1].get(), technology())
2552 .WillByDefault(Return(Technology::kWifi));
2553 ON_CALL(*mock_devices_[2].get(), technology())
2554 .WillByDefault(Return(Technology::kCellular));
2555 ON_CALL(*mock_devices_[3].get(), technology())
2556 .WillByDefault(Return(Technology::kWifi));
2557
2558 mock_devices_[0]->SelectService(connected_service1);
2559 mock_devices_[1]->SelectService(disconnected_service1);
2560 mock_devices_[2]->SelectService(disconnected_service2);
2561 mock_devices_[3]->SelectService(connected_service2);
2562
2563 set<string> expected_technologies;
2564 expected_technologies.insert(Technology::NameFromIdentifier(
2565 Technology::kEthernet));
2566 expected_technologies.insert(Technology::NameFromIdentifier(
2567 Technology::kWifi));
2568 Error error;
2569
2570 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2571 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2572 ContainerEq(expected_technologies));
2573}
2574
2575TEST_F(ManagerTest, DefaultTechnology) {
2576 scoped_refptr<MockService> connected_service(
2577 new NiceMock<MockService>(control_interface(),
2578 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002579 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002580 manager()));
2581 scoped_refptr<MockService> disconnected_service(
2582 new NiceMock<MockService>(control_interface(),
2583 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002584 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002585 manager()));
2586
2587 // Connected. WiFi.
2588 ON_CALL(*connected_service.get(), IsConnected())
2589 .WillByDefault(Return(true));
2590 ON_CALL(*connected_service.get(), state())
2591 .WillByDefault(Return(Service::kStateConnected));
2592 ON_CALL(*connected_service.get(), technology())
2593 .WillByDefault(Return(Technology::kWifi));
2594
2595 // Disconnected. Ethernet.
2596 ON_CALL(*disconnected_service.get(), technology())
2597 .WillByDefault(Return(Technology::kEthernet));
2598
2599 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002600 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002601 Error error;
2602 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2603
2604
2605 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002606 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002607 // Connected service should be brought to the front now.
2608 string expected_technology =
2609 Technology::NameFromIdentifier(Technology::kWifi);
2610 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2611}
2612
Paul Stewart212d60f2012-07-12 10:59:13 -07002613TEST_F(ManagerTest, Stop) {
2614 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002615 new NiceMock<MockProfile>(
2616 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002617 AdoptProfile(manager(), profile);
2618 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002619 new NiceMock<MockService>(control_interface(),
2620 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002621 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002622 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002623 manager()->RegisterService(service);
2624 manager()->RegisterDevice(mock_devices_[0]);
2625 EXPECT_CALL(*profile.get(),
2626 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2627 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002628 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002629 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2630 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002631 manager()->Stop();
2632}
2633
mukesh agrawal00917ce2011-11-22 23:56:55 +00002634TEST_F(ManagerTest, UpdateServiceConnected) {
2635 scoped_refptr<MockService> mock_service(
2636 new NiceMock<MockService>(control_interface(),
2637 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002638 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002639 manager()));
2640 manager()->RegisterService(mock_service);
2641 EXPECT_FALSE(mock_service->favorite());
2642 EXPECT_FALSE(mock_service->auto_connect());
2643
Gaurav Shah435de2c2011-11-17 19:01:07 -08002644 EXPECT_CALL(*mock_service.get(), IsConnected())
2645 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002646 manager()->UpdateService(mock_service);
2647 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2648 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002649 // SortServices test. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002650 EXPECT_TRUE(mock_service->favorite());
2651 EXPECT_TRUE(mock_service->auto_connect());
2652}
2653
Thieu Led4e9e552012-02-16 16:26:07 -08002654TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2655 // This tests the case where the user connects to a service that is
2656 // currently associated with a profile. We want to make sure that the
2657 // favorite flag is set and that the flag is saved to the current
2658 // profile.
2659 scoped_refptr<MockService> mock_service(
2660 new NiceMock<MockService>(control_interface(),
2661 dispatcher(),
2662 metrics(),
2663 manager()));
2664 manager()->RegisterService(mock_service);
2665 EXPECT_FALSE(mock_service->favorite());
2666 EXPECT_FALSE(mock_service->auto_connect());
2667
Gary Moraind93615e2012-04-27 11:50:03 -07002668 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002669 new MockProfile(
2670 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002671
Gary Moraind93615e2012-04-27 11:50:03 -07002672 mock_service->set_profile(profile);
2673 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002674 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002675 EXPECT_CALL(*profile,
2676 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002677 manager()->UpdateService(mock_service);
2678 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2679 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002680 // SortServices test. (crbug.com/206367)
Thieu Led4e9e552012-02-16 16:26:07 -08002681 EXPECT_TRUE(mock_service->favorite());
2682 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002683 // This releases the ref on the mock profile.
2684 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002685}
2686
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002687TEST_F(ManagerTest, SaveSuccessfulService) {
2688 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002689 new StrictMock<MockProfile>(
2690 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002691 AdoptProfile(manager(), profile);
2692 scoped_refptr<MockService> service(
2693 new NiceMock<MockService>(control_interface(),
2694 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002695 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002696 manager()));
2697
2698 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2699 ServiceRefPtr expect_service(service.get());
2700
2701 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2702 .WillOnce(Return(false));
2703 manager()->RegisterService(service);
2704
2705 EXPECT_CALL(*service.get(), state())
2706 .WillRepeatedly(Return(Service::kStateConnected));
2707 EXPECT_CALL(*service.get(), IsConnected())
2708 .WillRepeatedly(Return(true));
2709 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2710 .WillOnce(Return(true));
2711 manager()->UpdateService(service);
2712}
2713
Darin Petkove7c6ad32012-06-29 10:22:09 +02002714TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002715 MockProfile *profile0 =
2716 new MockProfile(control_interface(), metrics(), manager(), "");
2717 MockProfile *profile1 =
2718 new MockProfile(control_interface(), metrics(), manager(), "");
2719 MockProfile *profile2 =
2720 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002721 AdoptProfile(manager(), profile0); // Passes ownership.
2722 AdoptProfile(manager(), profile1); // Passes ownership.
2723 AdoptProfile(manager(), profile2); // Passes ownership.
2724 DeviceRefPtr device_ref(mock_devices_[0].get());
2725 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2726 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2727 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2728 manager()->UpdateDevice(mock_devices_[0]);
2729}
2730
Paul Stewart1b253142012-01-26 14:05:52 -08002731TEST_F(ManagerTest, EnumerateProfiles) {
2732 vector<string> profile_paths;
2733 for (size_t i = 0; i < 10; i++) {
2734 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002735 new StrictMock<MockProfile>(
2736 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002737 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002738 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2739 .WillOnce(Return(profile_paths.back()));
2740 AdoptProfile(manager(), profile);
2741 }
2742
2743 Error error;
2744 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2745 EXPECT_TRUE(error.IsSuccess());
2746 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2747 for (size_t i = 0; i < profile_paths.size(); i++) {
2748 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2749 }
2750}
2751
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002752TEST_F(ManagerTest, AutoConnectOnRegister) {
2753 MockServiceRefPtr service = MakeAutoConnectableService();
2754 EXPECT_CALL(*service.get(), AutoConnect());
2755 manager()->RegisterService(service);
2756 dispatcher()->DispatchPendingEvents();
2757}
2758
2759TEST_F(ManagerTest, AutoConnectOnUpdate) {
2760 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002761 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002762 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002763 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002764 manager()->RegisterService(service1);
2765 manager()->RegisterService(service2);
2766 dispatcher()->DispatchPendingEvents();
2767
2768 EXPECT_CALL(*service1.get(), AutoConnect());
2769 EXPECT_CALL(*service2.get(), state())
2770 .WillRepeatedly(Return(Service::kStateFailure));
2771 EXPECT_CALL(*service2.get(), IsFailed())
2772 .WillRepeatedly(Return(true));
2773 EXPECT_CALL(*service2.get(), IsConnected())
2774 .WillRepeatedly(Return(false));
2775 manager()->UpdateService(service2);
2776 dispatcher()->DispatchPendingEvents();
2777}
2778
2779TEST_F(ManagerTest, AutoConnectOnDeregister) {
2780 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002781 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002782 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002783 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002784 manager()->RegisterService(service1);
2785 manager()->RegisterService(service2);
2786 dispatcher()->DispatchPendingEvents();
2787
2788 EXPECT_CALL(*service1.get(), AutoConnect());
2789 manager()->DeregisterService(service2);
2790 dispatcher()->DispatchPendingEvents();
2791}
2792
Darin Petkov3ec55342012-09-28 14:04:44 +02002793TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2794 MockServiceRefPtr service = MakeAutoConnectableService();
2795 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2796 SetPowerManager();
2797 EXPECT_CALL(*service, AutoConnect()).Times(0);
2798 manager()->RegisterService(service);
2799 dispatcher()->DispatchPendingEvents();
2800}
2801
Darin Petkovca621542012-07-25 14:25:56 +02002802TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2803 MockServiceRefPtr service = MakeAutoConnectableService();
2804 SetPowerState(PowerManagerProxyDelegate::kMem);
2805 SetPowerManager();
2806 EXPECT_CALL(*service, AutoConnect()).Times(0);
2807 manager()->RegisterService(service);
2808 dispatcher()->DispatchPendingEvents();
2809}
2810
2811TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2812 MockServiceRefPtr service = MakeAutoConnectableService();
2813 SetPowerState(PowerManagerProxyDelegate::kOn);
2814 SetPowerManager();
2815 EXPECT_CALL(*service, AutoConnect());
2816 manager()->RegisterService(service);
2817 dispatcher()->DispatchPendingEvents();
2818}
2819
2820TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2821 MockServiceRefPtr service = MakeAutoConnectableService();
2822 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2823 SetPowerManager();
2824 EXPECT_CALL(*service, AutoConnect());
2825 manager()->RegisterService(service);
2826 dispatcher()->DispatchPendingEvents();
2827}
2828
Paul Stewart63864b62012-11-07 15:10:55 -08002829TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2830 SetRunning(false);
2831 MockServiceRefPtr service = MakeAutoConnectableService();
2832 EXPECT_CALL(*service, AutoConnect()).Times(0);
2833 manager()->RegisterService(service);
2834 dispatcher()->DispatchPendingEvents();
2835}
2836
Darin Petkovca621542012-07-25 14:25:56 +02002837TEST_F(ManagerTest, OnPowerStateChanged) {
2838 MockServiceRefPtr service = MakeAutoConnectableService();
2839 SetPowerState(PowerManagerProxyDelegate::kOn);
2840 SetPowerManager();
2841 EXPECT_CALL(*service, AutoConnect());
2842 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002843 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002844 dispatcher()->DispatchPendingEvents();
2845
mukesh agrawal784566d2012-08-08 18:32:58 -07002846 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002847 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2848 EXPECT_CALL(*service, AutoConnect());
2849 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002850 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002851
mukesh agrawal784566d2012-08-08 18:32:58 -07002852 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002853 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2854 EXPECT_CALL(*service, AutoConnect()).Times(0);
2855 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002856 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002857}
2858
Darin Petkov3ec55342012-09-28 14:04:44 +02002859TEST_F(ManagerTest, AddTerminationAction) {
2860 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002861 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002862 SetPowerManager();
2863 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2864 manager()->AddTerminationAction("action1", base::Closure());
2865 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2866 manager()->AddTerminationAction("action2", base::Closure());
2867}
2868
2869TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002870 const char kKey1[] = "action1";
2871 const char kKey2[] = "action2";
2872 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002873
2874 MockPowerManager &power_manager = *power_manager_;
2875 SetPowerManager();
2876
2877 // Removing an action when the hook table is empty should not result in any
2878 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002879 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002880 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2881 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2882 manager()->RemoveTerminationAction("unknown");
2883 Mock::VerifyAndClearExpectations(&power_manager);
2884
Daniel Eratf9753672013-01-24 10:17:02 -08002885 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2886 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002887 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002888 manager()->AddTerminationAction(kKey1, base::Closure());
2889 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2890 manager()->AddTerminationAction(kKey2, base::Closure());
2891
2892 // Removing an action that ends up with a non-empty hook table should not
2893 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002894 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002895 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2896 manager()->RemoveTerminationAction(kKey1);
2897 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2898 Mock::VerifyAndClearExpectations(&power_manager);
2899
2900 // Removing the last action should trigger unregistering from the power
2901 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002902 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2903 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002904 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2905 manager()->RemoveTerminationAction(kKey2);
2906 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2907}
2908
2909TEST_F(ManagerTest, RunTerminationActions) {
2910 TerminationActionTest test_action;
2911 const string kActionName = "action";
2912
2913 EXPECT_CALL(test_action, Done(_));
2914 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2915 test_action.AsWeakPtr()));
2916
2917 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2918 Bind(&TerminationActionTest::Action,
2919 test_action.AsWeakPtr()));
2920 test_action.set_manager(manager());
2921 EXPECT_CALL(test_action, Done(_));
2922 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2923 test_action.AsWeakPtr()));
2924}
2925
Daniel Erat0818cca2012-12-14 10:16:21 -08002926TEST_F(ManagerTest, OnSuspendImminent) {
2927 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002928 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08002929 EXPECT_CALL(*power_manager_,
2930 ReportSuspendReadiness(
2931 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002932 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002933 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02002934}
2935
2936TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002937 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02002938 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08002939 EXPECT_CALL(*power_manager_,
2940 ReportSuspendReadiness(
2941 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002942 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002943 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02002944}
2945
Paul Stewartc681fa02012-03-02 19:40:04 -08002946TEST_F(ManagerTest, RecheckPortal) {
2947 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
2948 .WillOnce(Return(false));
2949 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
2950 .WillOnce(Return(true));
2951 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
2952 .Times(0);
2953
2954 manager()->RegisterDevice(mock_devices_[0]);
2955 manager()->RegisterDevice(mock_devices_[1]);
2956 manager()->RegisterDevice(mock_devices_[2]);
2957
2958 manager()->RecheckPortal(NULL);
2959}
2960
Paul Stewartd215af62012-04-24 23:25:50 -07002961TEST_F(ManagerTest, RecheckPortalOnService) {
2962 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
2963 dispatcher(),
2964 metrics(),
2965 manager());
2966 EXPECT_CALL(*mock_devices_[0].get(),
2967 IsConnectedToService(IsRefPtrTo(service)))
2968 .WillOnce(Return(false));
2969 EXPECT_CALL(*mock_devices_[1].get(),
2970 IsConnectedToService(IsRefPtrTo(service)))
2971 .WillOnce(Return(true));
2972 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
2973 .WillOnce(Return(true));
2974 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
2975 .Times(0);
2976
2977 manager()->RegisterDevice(mock_devices_[0]);
2978 manager()->RegisterDevice(mock_devices_[1]);
2979 manager()->RegisterDevice(mock_devices_[2]);
2980
2981 manager()->RecheckPortalOnService(service);
2982}
2983
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002984TEST_F(ManagerTest, GetDefaultService) {
2985 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002986 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002987
2988 scoped_refptr<MockService> mock_service(
2989 new NiceMock<MockService>(control_interface(),
2990 dispatcher(),
2991 metrics(),
2992 manager()));
2993
2994 manager()->RegisterService(mock_service);
2995 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002996 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002997
2998 scoped_refptr<MockConnection> mock_connection(
2999 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07003000 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003001 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003002 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003003
Paul Stewartce4ec192012-03-14 12:53:46 -07003004 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003005 manager()->DeregisterService(mock_service);
3006}
3007
Paul Stewart13ed2252012-03-21 12:52:46 -07003008TEST_F(ManagerTest, GetServiceWithGUID) {
3009 scoped_refptr<MockService> mock_service0(
3010 new NiceMock<MockService>(control_interface(),
3011 dispatcher(),
3012 metrics(),
3013 manager()));
3014
3015 scoped_refptr<MockService> mock_service1(
3016 new NiceMock<MockService>(control_interface(),
3017 dispatcher(),
3018 metrics(),
3019 manager()));
3020
Paul Stewartcb59fed2012-03-21 21:14:46 -07003021 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3022 .Times(0);
3023 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3024 .Times(0);
3025
Paul Stewart13ed2252012-03-21 12:52:46 -07003026 manager()->RegisterService(mock_service0);
3027 manager()->RegisterService(mock_service1);
3028
3029 const string kGUID0 = "GUID0";
3030 const string kGUID1 = "GUID1";
3031
3032 {
3033 Error error;
3034 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3035 EXPECT_FALSE(error.IsSuccess());
3036 EXPECT_FALSE(service);
3037 }
3038
3039 KeyValueStore args;
3040 args.SetString(flimflam::kGuidProperty, kGUID1);
3041
3042 {
3043 Error error;
3044 ServiceRefPtr service = manager()->GetService(args, &error);
3045 EXPECT_EQ(Error::kInvalidArguments, error.type());
3046 EXPECT_FALSE(service);
3047 }
3048
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003049 mock_service0->SetGuid(kGUID0, NULL);
3050 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003051
3052 {
3053 Error error;
3054 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3055 EXPECT_TRUE(error.IsSuccess());
3056 EXPECT_EQ(mock_service0.get(), service.get());
3057 }
3058
3059 {
3060 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003061 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3062 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003063 ServiceRefPtr service = manager()->GetService(args, &error);
3064 EXPECT_TRUE(error.IsSuccess());
3065 EXPECT_EQ(mock_service1.get(), service.get());
3066 }
3067
3068 manager()->DeregisterService(mock_service0);
3069 manager()->DeregisterService(mock_service1);
3070}
3071
Gary Morain028545d2012-04-07 14:55:52 -07003072
3073TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003074 EXPECT_FALSE(manager()->IsOnline());
3075 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3076
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003077 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003078 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003079 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3080 .Times(AnyNumber());
3081 scoped_refptr<MockService> mock_service0(
3082 new NiceMock<MockService>(control_interface(),
3083 dispatcher(),
3084 metrics(),
3085 manager()));
3086
3087 scoped_refptr<MockService> mock_service1(
3088 new NiceMock<MockService>(control_interface(),
3089 dispatcher(),
3090 metrics(),
3091 manager()));
3092
3093 EXPECT_CALL(*mock_service0.get(), IsConnected())
3094 .WillRepeatedly(Return(false));
3095 EXPECT_CALL(*mock_service1.get(), IsConnected())
3096 .WillRepeatedly(Return(false));
3097
3098 manager()->RegisterService(mock_service0);
3099 manager()->RegisterService(mock_service1);
3100
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003101 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003102 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3103
3104 manager()->DeregisterService(mock_service0);
3105 manager()->DeregisterService(mock_service1);
3106}
3107
3108TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003109 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003110 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003111 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3112 .Times(AnyNumber());
3113 scoped_refptr<MockService> mock_service0(
3114 new NiceMock<MockService>(control_interface(),
3115 dispatcher(),
3116 metrics(),
3117 manager()));
3118
3119 scoped_refptr<MockService> mock_service1(
3120 new NiceMock<MockService>(control_interface(),
3121 dispatcher(),
3122 metrics(),
3123 manager()));
3124
3125 EXPECT_CALL(*mock_service0.get(), IsConnected())
3126 .WillRepeatedly(Return(false));
3127 EXPECT_CALL(*mock_service1.get(), IsConnected())
3128 .WillRepeatedly(Return(true));
3129 EXPECT_CALL(*mock_service0.get(), state())
3130 .WillRepeatedly(Return(Service::kStateIdle));
3131 EXPECT_CALL(*mock_service1.get(), state())
3132 .WillRepeatedly(Return(Service::kStateConnected));
3133
3134 manager()->RegisterService(mock_service0);
3135 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003136 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003137
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003138 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003139 EXPECT_EQ("online", manager()->CalculateState(NULL));
3140
3141 manager()->DeregisterService(mock_service0);
3142 manager()->DeregisterService(mock_service1);
3143}
3144
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003145TEST_F(ManagerTest, StartupPortalList) {
3146 // Simulate loading value from the default profile.
3147 const string kProfileValue("wifi,vpn");
3148 manager()->props_.check_portal_list = kProfileValue;
3149
3150 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3151 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3152 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3153
3154 const string kStartupValue("cellular,ethernet");
3155 manager()->SetStartupPortalList(kStartupValue);
3156 // Ensure profile value is not overwritten, so when we save the default
3157 // profile, the correct value will still be written.
3158 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3159
3160 // However we should read back a different list.
3161 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3162 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3163 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3164
3165 const string kRuntimeValue("ppp");
3166 // Setting a runtime value over the control API should overwrite both
3167 // the profile value and what we read back.
3168 Error error;
3169 manager()->mutable_store()->SetStringProperty(
3170 flimflam::kCheckPortalListProperty,
3171 kRuntimeValue,
3172 &error);
3173 ASSERT_TRUE(error.IsSuccess());
3174 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3175 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3176 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3177 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3178}
3179
Paul Stewart036dba02012-08-07 12:34:41 -07003180TEST_F(ManagerTest, LinkMonitorEnabled) {
3181 const string kEnabledTechnologies("wifi,vpn");
3182 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3183 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3184 EXPECT_FALSE(
3185 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3186}
3187
Paul Stewart85aea152013-01-22 09:31:56 -08003188TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003189 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003190 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003191 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003192 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003193 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003194 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3195 AdoptProfile(manager(), profile);
3196 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3197 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3198 scoped_ptr<MockStore> store1(new MockStore);
3199 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3200}
3201
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003202TEST_F(ManagerTest, EnableTechnology) {
3203 Error error(Error::kOperationInitiated);
3204 ResultCallback callback;
3205 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3206 EXPECT_TRUE(error.IsSuccess());
3207
Joshua Krollda798622012-06-05 12:30:48 -07003208 ON_CALL(*mock_devices_[0], technology())
3209 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003210
3211 manager()->RegisterDevice(mock_devices_[0]);
3212
3213 // Device is enabled, so expect operation is successful.
3214 mock_devices_[0]->enabled_ = true;
3215 error.Populate(Error::kOperationInitiated);
3216 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3217 EXPECT_TRUE(error.IsSuccess());
3218
3219 // Device is disabled, so expect operation in progress.
3220 mock_devices_[0]->enabled_ = false;
3221 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3222 error.Populate(Error::kOperationInitiated);
3223 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3224 EXPECT_TRUE(error.IsOngoing());
3225}
3226
3227TEST_F(ManagerTest, DisableTechnology) {
3228 Error error(Error::kOperationInitiated);
3229 ResultCallback callback;
3230 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3231 EXPECT_TRUE(error.IsSuccess());
3232
Joshua Krollda798622012-06-05 12:30:48 -07003233 ON_CALL(*mock_devices_[0], technology())
3234 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003235
3236 manager()->RegisterDevice(mock_devices_[0]);
3237
3238 // Device is disabled, so expect operation is successful.
3239 error.Populate(Error::kOperationInitiated);
3240 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3241 EXPECT_TRUE(error.IsSuccess());
3242
3243 // Device is enabled, so expect operation in progress.
3244 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3245 mock_devices_[0]->enabled_ = true;
3246 error.Populate(Error::kOperationInitiated);
3247 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3248 EXPECT_TRUE(error.IsOngoing());
3249}
3250
Paul Stewart4d5efb72012-09-17 12:24:34 -07003251TEST_F(ManagerTest, IgnoredSearchList) {
3252 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003253 vector<string> ignored_paths;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003254 SetResolver(resolver.get());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003255
3256 const string kIgnored0 = "chromium.org";
3257 ignored_paths.push_back(kIgnored0);
3258 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003259 SetIgnoredDNSSearchPaths(kIgnored0, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003260 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3261
3262 const string kIgnored1 = "google.com";
3263 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3264 ignored_paths.push_back(kIgnored1);
3265 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003266 SetIgnoredDNSSearchPaths(kIgnoredSum, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003267 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3268
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003269 ignored_paths.clear();
3270 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3271 SetIgnoredDNSSearchPaths("", NULL);
3272 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3273
Paul Stewart4d5efb72012-09-17 12:24:34 -07003274 SetResolver(Resolver::GetInstance());
3275}
3276
Paul Stewartbfb82552012-10-24 16:48:48 -07003277TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3278 // Test to make sure that every service state-change causes the
3279 // Manager to emit a new service list.
3280 scoped_refptr<MockService> mock_service(
3281 new NiceMock<MockService>(control_interface(),
3282 dispatcher(),
3283 metrics(),
3284 manager()));
3285 EXPECT_CALL(*mock_service, state())
3286 .WillRepeatedly(Return(Service::kStateIdle));
3287
3288 manager()->RegisterService(mock_service);
3289 EXPECT_CALL(
3290 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3291 flimflam::kServicesProperty, _)).Times(1);
3292 EXPECT_CALL(
3293 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3294 flimflam::kServiceWatchListProperty, _)).Times(1);
3295 CompleteServiceSort();
3296
3297 Mock::VerifyAndClearExpectations(manager_adaptor_);
3298 EXPECT_CALL(
3299 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3300 flimflam::kServicesProperty, _)).Times(1);
3301 EXPECT_CALL(
3302 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3303 flimflam::kServiceWatchListProperty, _)).Times(1);
3304 manager()->UpdateService(mock_service.get());
3305 CompleteServiceSort();
3306
3307 manager()->DeregisterService(mock_service);
3308}
3309
3310TEST_F(ManagerTest, EnumerateServices) {
3311 scoped_refptr<MockService> mock_service(
3312 new NiceMock<MockService>(control_interface(),
3313 dispatcher(),
3314 metrics(),
3315 manager()));
3316 manager()->RegisterService(mock_service);
3317
3318 EXPECT_CALL(*mock_service, state())
3319 .WillRepeatedly(Return(Service::kStateConnected));
3320 EXPECT_CALL(*mock_service, IsVisible())
3321 .WillRepeatedly(Return(false));
3322 EXPECT_TRUE(EnumerateAvailableServices().empty());
3323 EXPECT_TRUE(EnumerateWatchedServices().empty());
3324
3325 EXPECT_CALL(*mock_service, state())
3326 .WillRepeatedly(Return(Service::kStateIdle));
3327 EXPECT_TRUE(EnumerateAvailableServices().empty());
3328 EXPECT_TRUE(EnumerateWatchedServices().empty());
3329
3330 EXPECT_CALL(*mock_service, IsVisible())
3331 .WillRepeatedly(Return(true));
3332 Service::ConnectState unwatched_states[] = {
3333 Service::kStateUnknown,
3334 Service::kStateIdle,
3335 Service::kStateFailure
3336 };
3337 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3338 EXPECT_CALL(*mock_service, state())
3339 .WillRepeatedly(Return(unwatched_states[i]));
3340 EXPECT_FALSE(EnumerateAvailableServices().empty());
3341 EXPECT_TRUE(EnumerateWatchedServices().empty());
3342 }
3343
3344 Service::ConnectState watched_states[] = {
3345 Service::kStateAssociating,
3346 Service::kStateConfiguring,
3347 Service::kStateConnected,
Paul Stewartbfb82552012-10-24 16:48:48 -07003348 Service::kStatePortal,
3349 Service::kStateOnline
3350 };
3351 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3352 EXPECT_CALL(*mock_service, state())
3353 .WillRepeatedly(Return(watched_states[i]));
3354 EXPECT_FALSE(EnumerateAvailableServices().empty());
3355 EXPECT_FALSE(EnumerateWatchedServices().empty());
3356 }
3357
3358 manager()->DeregisterService(mock_service);
3359}
3360
Paul Stewart39db5ca2013-03-18 14:15:17 -07003361TEST_F(ManagerTest, ConnectToBestServices) {
3362 scoped_refptr<MockService> wifi_service0(
3363 new NiceMock<MockService>(control_interface(),
3364 dispatcher(),
3365 metrics(),
3366 manager()));
3367 EXPECT_CALL(*wifi_service0.get(), state())
3368 .WillRepeatedly(Return(Service::kStateIdle));
3369 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3370 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003371 wifi_service0->SetConnectable(true);
3372 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003373 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3374 EXPECT_CALL(*wifi_service0.get(), technology())
3375 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003376 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3377 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003378
3379 scoped_refptr<MockService> wifi_service1(
3380 new NiceMock<MockService>(control_interface(),
3381 dispatcher(),
3382 metrics(),
3383 manager()));
3384 EXPECT_CALL(*wifi_service1.get(), state())
3385 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003386 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3387 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003388 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3389 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003390 wifi_service1->SetAutoConnect(true);
3391 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003392 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3393 EXPECT_CALL(*wifi_service1.get(), technology())
3394 .WillRepeatedly(Return(Technology::kWifi));
3395
3396 scoped_refptr<MockService> wifi_service2(
3397 new NiceMock<MockService>(control_interface(),
3398 dispatcher(),
3399 metrics(),
3400 manager()));
3401 EXPECT_CALL(*wifi_service2.get(), state())
3402 .WillRepeatedly(Return(Service::kStateConnected));
3403 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3404 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003405 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3406 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003407 wifi_service2->SetAutoConnect(true);
3408 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003409 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3410 EXPECT_CALL(*wifi_service2.get(), technology())
3411 .WillRepeatedly(Return(Technology::kWifi));
3412
3413 manager()->RegisterService(wifi_service0);
3414 manager()->RegisterService(wifi_service1);
3415 manager()->RegisterService(wifi_service2);
3416
3417 CompleteServiceSort();
3418 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3419
3420 scoped_refptr<MockService> cell_service(
3421 new NiceMock<MockService>(control_interface(),
3422 dispatcher(),
3423 metrics(),
3424 manager()));
3425
3426 EXPECT_CALL(*cell_service.get(), state())
3427 .WillRepeatedly(Return(Service::kStateConnected));
3428 EXPECT_CALL(*cell_service.get(), IsConnected())
3429 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003430 EXPECT_CALL(*cell_service.get(), IsVisible())
3431 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003432 wifi_service2->SetAutoConnect(true);
3433 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003434 EXPECT_CALL(*cell_service.get(), technology())
3435 .WillRepeatedly(Return(Technology::kCellular));
3436 manager()->RegisterService(cell_service);
3437
3438 scoped_refptr<MockService> vpn_service(
3439 new NiceMock<MockService>(control_interface(),
3440 dispatcher(),
3441 metrics(),
3442 manager()));
3443
3444 EXPECT_CALL(*vpn_service.get(), state())
3445 .WillRepeatedly(Return(Service::kStateIdle));
3446 EXPECT_CALL(*vpn_service.get(), IsConnected())
3447 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003448 EXPECT_CALL(*vpn_service.get(), IsVisible())
3449 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003450 wifi_service2->SetAutoConnect(false);
3451 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003452 EXPECT_CALL(*vpn_service.get(), technology())
3453 .WillRepeatedly(Return(Technology::kVPN));
3454 manager()->RegisterService(vpn_service);
3455
3456 // The connected services should be at the top.
3457 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3458
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003459 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3460 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003461 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
3462 EXPECT_CALL(*cell_service.get(), Connect(_, _)).Times(0); // Is connected.
3463 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003464
3465 manager()->ConnectToBestServices(NULL);
3466 dispatcher()->DispatchPendingEvents();
3467
3468 // After this operation, since the Connect calls above are mocked and
3469 // no actual state changes have occurred, we should expect that the
3470 // service sorting order will not have changed.
3471 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3472}
3473
Christopher Wiley83889862013-05-02 15:55:09 -07003474TEST_F(ManagerTest, VerifyWhenNotConnected) {
3475 const string kFakeCertificate("fake cert");
3476 const string kFakePublicKey("fake public key");
3477 const string kFakeNonce("fake public key");
3478 const string kFakeSignedData("fake signed data");
3479 const string kFakeUdn("fake udn");
3480 const vector<uint8_t> kSSID(10, 87);
3481 const string kConfiguredSSID("AConfiguredDestination");
3482 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3483 kConfiguredSSID.end());
3484 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
3485 scoped_refptr<MockWiFiService> mock_destination(
3486 new NiceMock<MockWiFiService>(control_interface(), dispatcher(),
3487 metrics(), manager(), wifi_provider_,
3488 kSSID, "", "none", false));
3489 // Register this service, but don't mark it as connected.
3490 manager()->RegisterService(mock_destination);
3491 // Verify that if we're not connected to anything, verification fails.
3492 {
3493 LOG(INFO) << "Can't verify if not connected.";
3494 EXPECT_CALL(*crypto_util_proxy_,
3495 VerifyDestination(_, _, _, _, _, _, _, _, _)).Times(0);
3496 Error error(Error::kOperationInitiated);
3497 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3498 kFakeSignedData, kFakeUdn, "", "",
3499 ResultBoolCallback(), &error);
3500 EXPECT_TRUE(error.IsFailure());
3501 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3502 }
3503 {
3504 // However, if the destination is already configured, we might be
3505 // connected to it via something other than WiFi, and we shouldn't
3506 // enforce the WiFi check.
3507 EXPECT_CALL(*crypto_util_proxy_,
3508 VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3509 kFakeSignedData, kFakeUdn,
3510 kConfiguredSSIDVector, kConfiguredBSSID,
3511 _, _)).Times(1).WillOnce(Return(true));
3512 Error error(Error::kOperationInitiated);
3513 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3514 kFakeSignedData, kFakeUdn, kConfiguredSSID,
3515 kConfiguredBSSID, ResultBoolCallback(),
3516 &error);
3517 EXPECT_FALSE(error.IsFailure());
3518 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3519 }
3520}
3521
Christopher Wiley1057cd72013-02-28 15:21:29 -08003522TEST_F(ManagerTest, VerifyDestination) {
3523 const string kFakeCertificate("fake cert");
3524 const string kFakePublicKey("fake public key");
3525 const string kFakeNonce("fake public key");
3526 const string kFakeSignedData("fake signed data");
3527 const string kFakeUdn("fake udn");
3528 const char kSSIDStr[] = "fake ssid";
3529 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
Christopher Wileycdde79f2013-05-01 14:26:56 -07003530 const string kConfiguredSSID("AConfiguredDestination");
3531 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3532 kConfiguredSSID.end());
3533 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
Christopher Wiley1057cd72013-02-28 15:21:29 -08003534 const string kFakeData("muffin man");
3535 scoped_refptr<MockWiFiService> mock_destination(
3536 new NiceMock<MockWiFiService>(control_interface(),
3537 dispatcher(),
3538 metrics(),
3539 manager(),
3540 wifi_provider_,
3541 kSSID,
3542 "",
3543 "none",
3544 false));
3545 manager()->RegisterService(mock_destination);
Christopher Wiley1057cd72013-02-28 15:21:29 -08003546 // Making the service look online will let service lookup in
3547 // VerifyDestinatoin succeed.
3548 EXPECT_CALL(*mock_destination.get(), IsConnected())
3549 .WillRepeatedly(Return(true));
Christopher Wiley83889862013-05-02 15:55:09 -07003550 StrictMock<DestinationVerificationTest> dv_test;
Christopher Wiley1057cd72013-02-28 15:21:29 -08003551
3552 // Lead off by verifying that the basic VerifyDestination flow works.
3553 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003554 LOG(INFO) << "Basic VerifyDestination flow.";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003555 ResultBoolCallback passed_down_callback;
3556 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3557 kFakePublicKey,
3558 kFakeNonce,
3559 kFakeSignedData,
3560 kFakeUdn,
3561 kSSID,
3562 _,
3563 _,
3564 _))
3565 .Times(1)
3566 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3567 // Ask the manager to verify the current destination. This should look
3568 // up our previously registered service, and pass some metadata about
3569 // that service down to the CryptoUtilProxy to verify.
3570 Error error(Error::kOperationInitiated);
3571 ResultBoolCallback cb = Bind(
3572 &DestinationVerificationTest::ResultBoolCallbackStub,
3573 dv_test.AsWeakPtr());
3574 manager()->VerifyDestination(kFakeCertificate,
3575 kFakePublicKey,
3576 kFakeNonce,
3577 kFakeSignedData,
3578 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003579 // Ask to be verified against that service.
3580 "", "",
3581 cb,
3582 &error);
3583 // We assert here, because if the operation is not ongoing, it is
3584 // inconsistent with shim behavior to call the callback anyway.
3585 ASSERT_TRUE(error.IsOngoing());
3586 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3587 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3588 // Call the callback passed into the CryptoUtilProxy, which
3589 // should find its way into the callback passed into the manager.
3590 // In real code, that callback passed into the manager is from the
3591 // DBus adaptor.
3592 Error e;
3593 passed_down_callback.Run(e, true);
3594 Mock::VerifyAndClearExpectations(&dv_test);
3595 }
3596
Christopher Wiley1057cd72013-02-28 15:21:29 -08003597 // Now for a slightly more complex variant. When we encrypt data,
3598 // we do the same verification step but monkey with the callback to
3599 // link ourselves to an encrypt step afterward.
3600 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003601 LOG(INFO) << "Basic VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003602 ResultBoolCallback passed_down_callback;
3603 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3604 kFakePublicKey,
3605 kFakeNonce,
3606 kFakeSignedData,
3607 kFakeUdn,
3608 kSSID,
3609 _,
3610 _,
3611 _))
3612 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3613
3614 Error error(Error::kOperationInitiated);
3615 ResultStringCallback cb = Bind(
3616 &DestinationVerificationTest::ResultStringCallbackStub,
3617 dv_test.AsWeakPtr());
3618 manager()->VerifyAndEncryptData(kFakeCertificate,
3619 kFakePublicKey,
3620 kFakeNonce,
3621 kFakeSignedData,
3622 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003623 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003624 kFakeData,
3625 cb,
3626 &error);
3627 ASSERT_TRUE(error.IsOngoing());
3628 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3629 // Now, if we call that passed down callback, we should see encrypt being
3630 // called.
3631 ResultStringCallback second_passed_down_callback;
3632 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3633 kFakeData,
3634 _,
3635 _))
3636 .Times(1)
3637 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3638 Return(true)));
3639 Error e;
3640 passed_down_callback.Run(e, true);
3641 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3642 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3643 // And if we call the second passed down callback, we should see the
3644 // original function we passed down to VerifyDestination getting called.
3645 e.Reset();
3646 second_passed_down_callback.Run(e, "");
3647 Mock::VerifyAndClearExpectations(&dv_test);
3648 }
3649
3650 // If verification fails on the way to trying to encrypt, we should ditch
3651 // without calling encrypt at all.
3652 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003653 LOG(INFO) << "Failed VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003654 ResultBoolCallback passed_down_callback;
3655 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3656 kFakePublicKey,
3657 kFakeNonce,
3658 kFakeSignedData,
3659 kFakeUdn,
3660 kSSID,
3661 _,
3662 _,
3663 _))
3664 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3665
3666 Error error(Error::kOperationInitiated);
3667 ResultStringCallback cb = Bind(
3668 &DestinationVerificationTest::ResultStringCallbackStub,
3669 dv_test.AsWeakPtr());
3670 manager()->VerifyAndEncryptData(kFakeCertificate,
3671 kFakePublicKey,
3672 kFakeNonce,
3673 kFakeSignedData,
3674 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003675 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003676 kFakeData,
3677 cb,
3678 &error);
3679 ASSERT_TRUE(error.IsOngoing());
3680 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3681 Error e(Error::kOperationFailed);
3682 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3683 // Although we're ditching, this callback is what cleans up the pending
3684 // DBus call.
3685 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3686 passed_down_callback.Run(e, false);
3687 Mock::VerifyAndClearExpectations(&dv_test);
3688 }
3689}
3690
Paul Stewartd2e1c362013-03-03 19:06:07 -08003691TEST_F(ManagerTest, IsProfileBefore) {
3692 scoped_refptr<MockProfile> profile0(
3693 new NiceMock<MockProfile>(
3694 control_interface(), metrics(), manager(), ""));
3695 scoped_refptr<MockProfile> profile1(
3696 new NiceMock<MockProfile>(
3697 control_interface(), metrics(), manager(), ""));
3698
3699 AdoptProfile(manager(), profile0);
3700 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3701 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3702 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3703
3704 // A few abnormal cases, but it's good to track their behavior.
3705 scoped_refptr<MockProfile> profile2(
3706 new NiceMock<MockProfile>(
3707 control_interface(), metrics(), manager(), ""));
3708 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3709 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3710 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3711 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3712}
3713
Paul Stewart967eaeb2013-04-25 19:53:07 -07003714TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
3715 MockStore storage0;
3716 MockStore storage1;
3717 MockStore storage2;
3718
3719 scoped_refptr<MockProfile> profile0(
3720 new NiceMock<MockProfile>(
3721 control_interface(), metrics(), manager(), ""));
3722 scoped_refptr<MockProfile> profile1(
3723 new NiceMock<MockProfile>(
3724 control_interface(), metrics(), manager(), ""));
3725 scoped_refptr<MockProfile> profile2(
3726 new NiceMock<MockProfile>(
3727 control_interface(), metrics(), manager(), ""));
3728
3729 AdoptProfile(manager(), profile0);
3730 AdoptProfile(manager(), profile1);
3731 AdoptProfile(manager(), profile2);
3732
3733 scoped_refptr<MockService> service(
3734 new NiceMock<MockService>(control_interface(),
3735 dispatcher(),
3736 metrics(),
3737 manager()));
3738
3739 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
3740 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
3741 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
3742
3743 const string kEntry0("aluminum_crutch");
3744 const string kEntry2("rehashed_faces");
3745
3746 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
3747 .WillOnce(Return(kEntry0));
3748 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
3749 .WillOnce(Return(""));
3750 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
3751 .WillOnce(Return(kEntry2));
3752
3753 const string kProfileRpc0("service_station");
3754 const string kProfileRpc2("crystal_tiaras");
3755
3756 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
3757 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
3758 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
3759
3760 map<string, string> entries =
3761 manager()->GetLoadableProfileEntriesForService(service);
3762 EXPECT_EQ(2, entries.size());
3763 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
3764 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
3765 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
3766 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
3767}
3768
mukesh agrawal00752532013-05-03 15:46:55 -07003769TEST_F(ManagerTest, InitializeProfilesInformsProviders) {
mukesh agrawald142fd62013-05-01 16:50:57 -07003770 // We need a real glib here, so that profiles are persisted.
3771 GLib glib;
3772 ScopedTempDir temp_dir;
3773 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3774 Manager manager(control_interface(),
3775 dispatcher(),
3776 metrics(),
3777 &glib,
3778 run_path(),
3779 storage_path(),
3780 temp_dir.path().value());
3781 // Can't use |wifi_provider_|, because it's owned by the Manager
3782 // object in the fixture.
3783 MockWiFiProvider *wifi_provider = new NiceMock<MockWiFiProvider>();
3784 manager.wifi_provider_.reset(wifi_provider); // pass ownership
3785 // Give manager a valid place to write the user profile list.
3786 manager.user_profile_list_path_ = temp_dir.path().Append("user_profile_list");
3787
3788 // With no user profiles, the WiFiProvider should be called once
3789 // (for the default profile).
3790 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_));
3791 manager.InitializeProfiles();
3792 Mock::VerifyAndClearExpectations(wifi_provider);
3793
3794 // With |n| user profiles, the WiFiProvider should be called |n+1|
3795 // times. First, create 2 user profiles...
3796 const char kProfile0[] = "~user/profile0";
3797 const char kProfile1[] = "~user/profile1";
3798 string profile_rpc_path;
3799 Error error;
3800 manager.CreateProfile(kProfile0, &profile_rpc_path, &error);
3801 manager.PushProfile(kProfile0, &profile_rpc_path, &error);
3802 manager.CreateProfile(kProfile1, &profile_rpc_path, &error);
3803 manager.PushProfile(kProfile1, &profile_rpc_path, &error);
3804
3805 // ... then reset manager state ...
3806 manager.profiles_.clear();
3807
3808 // ...then check that the WiFiProvider is notified about all three
3809 // profiles (one default, two user).
3810 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_)).Times(3);
3811 manager.InitializeProfiles();
3812 Mock::VerifyAndClearExpectations(wifi_provider);
3813}
3814
mukesh agrawal00752532013-05-03 15:46:55 -07003815TEST_F(ManagerTest, InitializeProfilesHandlesDefaults) {
3816 // We need a real glib here, so that profiles are persisted.
3817 GLib glib;
3818 ScopedTempDir temp_dir;
3819 scoped_ptr<Manager> manager;
3820 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3821
3822 // Instantiate a Manager with empty persistent storage. Check that
3823 // defaults are set.
3824 //
3825 // Note that we use the same directory for default and user profiles.
3826 // This doesn't affect the test results, because we don't push a
3827 // user profile.
3828 manager.reset(new Manager(control_interface(),
3829 dispatcher(),
3830 metrics(),
3831 &glib,
3832 run_path(),
3833 temp_dir.path().value(),
3834 temp_dir.path().value()));
3835 manager->InitializeProfiles();
3836 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
3837 manager->props_.check_portal_list);
3838 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
3839 manager->props_.ignored_dns_search_paths);
3840 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
3841 manager->props_.link_monitor_technologies);
3842 EXPECT_EQ(PortalDetector::kDefaultURL,
3843 manager->props_.portal_url);
3844 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
3845 manager->props_.portal_check_interval_seconds);
3846
3847 // Change one of the settings.
3848 static const string kCustomCheckPortalList = "fiber0";
3849 Error error;
3850 manager->SetCheckPortalList(kCustomCheckPortalList, &error);
3851 manager->profiles_[0]->Save();
3852
3853 // Instantiate a new manager. It should have our settings for
3854 // check_portal_list, rather than the default.
3855 manager.reset(new Manager(control_interface(),
3856 dispatcher(),
3857 metrics(),
3858 &glib,
3859 run_path(),
3860 temp_dir.path().value(),
3861 temp_dir.path().value()));
3862 manager->InitializeProfiles();
3863 EXPECT_EQ(kCustomCheckPortalList, manager->props_.check_portal_list);
3864
3865 // If we clear the persistent storage, we again get the default value.
3866 ASSERT_TRUE(temp_dir.Delete());
3867 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3868 manager.reset(new Manager(control_interface(),
3869 dispatcher(),
3870 metrics(),
3871 &glib,
3872 run_path(),
3873 temp_dir.path().value(),
3874 temp_dir.path().value()));
3875 manager->InitializeProfiles();
3876 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
3877 manager->props_.check_portal_list);
3878}
3879
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003880// Custom property setters should return false, and make no changes, if
3881// the new value is the same as the old value.
3882TEST_F(ManagerTest, CustomSetterNoopChange) {
3883 // SetCheckPortalList
3884 {
3885 static const string kCheckPortalList = "weird-device,weirder-device";
3886 Error error;
3887 // Set to known value.
3888 EXPECT_TRUE(SetCheckPortalList(kCheckPortalList, &error));
3889 EXPECT_TRUE(error.IsSuccess());
3890 // Set to same value.
3891 EXPECT_FALSE(SetCheckPortalList(kCheckPortalList, &error));
3892 EXPECT_TRUE(error.IsSuccess());
3893 }
3894
3895 // SetIgnoredDNSSearchPaths
3896 {
3897 NiceMock<MockResolver> resolver;
3898 static const string kIgnoredPaths = "example.com,example.org";
3899 Error error;
3900 SetResolver(&resolver);
3901 // Set to known value.
3902 EXPECT_CALL(resolver, set_ignored_search_list(_));
3903 EXPECT_TRUE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
3904 EXPECT_TRUE(error.IsSuccess());
3905 Mock::VerifyAndClearExpectations(&resolver);
3906 // Set to same value.
3907 EXPECT_CALL(resolver, set_ignored_search_list(_)).Times(0);
3908 EXPECT_FALSE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
3909 EXPECT_TRUE(error.IsSuccess());
3910 Mock::VerifyAndClearExpectations(&resolver);
3911 }
3912}
3913
Chris Masone9be4a9d2011-05-16 15:44:09 -07003914} // namespace shill