blob: ef006ae3907fce54cd1dcc0caf2d534401bcd10c [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>
Ben Chana0ddf462014-02-06 11:32:42 -080015#include <base/strings/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"
Paul Stewart7de7e022013-08-28 09:42:50 -070023#include "shill/geolocation_info.h"
Chris Masone6515aab2011-10-12 16:19:09 -070024#include "shill/glib.h"
25#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070026#include "shill/key_value_store.h"
mukesh agrawal00752532013-05-03 15:46:55 -070027#include "shill/link_monitor.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070028#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070029#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080030#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070031#include "shill/mock_control.h"
Christopher Wiley1057cd72013-02-28 15:21:29 -080032#include "shill/mock_crypto_util_proxy.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070033#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080034#include "shill/mock_device_info.h"
Paul Stewart35eff132013-04-12 12:08:40 -070035#include "shill/mock_ethernet_eap_provider.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070036#include "shill/mock_glib.h"
mukesh agrawalb94adde2013-08-22 18:17:26 -070037#include "shill/mock_log.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000038#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020039#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070040#include "shill/mock_profile.h"
Ben Chana55469d2014-01-27 16:35:29 -080041#include "shill/mock_proxy_factory.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070042#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070043#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070044#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080045#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070046#include "shill/mock_wifi_service.h"
mukesh agrawal00752532013-05-03 15:46:55 -070047#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070048#include "shill/property_store_unittest.h"
mukesh agrawal00752532013-05-03 15:46:55 -070049#include "shill/resolver.h"
Chris Masone6515aab2011-10-12 16:19:09 -070050#include "shill/service_under_test.h"
Paul Stewartf2860342014-05-09 14:29:16 -070051#include "shill/testing.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070052#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020053#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070054
Christopher Wiley1057cd72013-02-28 15:21:29 -080055using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080056using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080057using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070058using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070059using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070060using std::string;
61using std::vector;
62
Chris Masone9be4a9d2011-05-16 15:44:09 -070063namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070064using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070065using ::testing::AnyNumber;
Paul Stewart7de7e022013-08-28 09:42:50 -070066using ::testing::AtLeast;
Gaurav Shah435de2c2011-11-17 19:01:07 -080067using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070068using ::testing::DoAll;
mukesh agrawalb94adde2013-08-22 18:17:26 -070069using ::testing::HasSubstr;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070070using ::testing::InSequence;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070071using ::testing::Invoke;
mukesh agrawal784566d2012-08-08 18:32:58 -070072using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070073using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070074using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070075using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070076using ::testing::Return;
Ben Chana55469d2014-01-27 16:35:29 -080077using ::testing::ReturnNull;
Paul Stewartce4ec192012-03-14 12:53:46 -070078using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070079using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080080using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080081using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080082using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070083using ::testing::Test;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070084using ::testing::WithArg;
Chris Masone9be4a9d2011-05-16 15:44:09 -070085
Chris Masone3bd3c8c2011-06-13 08:20:26 -070086class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070087 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070088 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020089 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080090 device_info_(new NiceMock<MockDeviceInfo>(
91 control_interface(),
92 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080093 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080094 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080095 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070096 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080097 wifi_provider_(new NiceMock<MockWiFiProvider>()),
98 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
99 glib())) {
Ben Chana55469d2014-01-27 16:35:29 -0800100 ON_CALL(proxy_factory_, CreatePowerManagerProxy(_))
101 .WillByDefault(ReturnNull());
102
Paul Stewart22aa71b2011-09-16 12:15:11 -0700103 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
104 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800105 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700106 manager(),
107 "null0",
108 "addr0",
109 0));
110 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
111 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800112 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700113 manager(),
114 "null1",
115 "addr1",
116 1));
117 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
118 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800119 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700120 manager(),
121 "null2",
122 "addr2",
123 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800124 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
125 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800126 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800127 manager(),
128 "null3",
129 "addr3",
130 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700131 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800132 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800133
134 // Replace the manager's adaptor with a quieter one, and one
135 // we can do EXPECT*() against. Passes ownership.
136 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800137
Paul Stewart35eff132013-04-12 12:08:40 -0700138 // Replace the manager's Ethernet EAP provider with our mock.
139 // Passes ownership.
140 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
141
Paul Stewart3c504012013-01-17 17:49:58 -0800142 // Replace the manager's WiFi provider with our mock. Passes
143 // ownership.
144 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800145
Paul Stewartb87d22b2013-07-29 11:11:37 -0700146 // Update the manager's map from technology to provider.
147 manager()->UpdateProviderMapping();
148
Christopher Wiley1057cd72013-02-28 15:21:29 -0800149 // Replace the manager's crypto util proxy with our mock. Passes
150 // ownership.
151 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700152 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700153 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700154
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100155 void SetMetrics(Metrics *metrics) {
156 manager()->set_metrics(metrics);
157 }
158
Paul Stewartfdd16072011-09-16 12:41:35 -0700159 bool IsDeviceRegistered(const DeviceRefPtr &device,
160 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700161 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700162 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700163 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700164 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700165 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700166
Paul Stewarta849a3d2011-11-03 05:54:09 -0700167 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
168 manager->profiles_.push_back(profile);
169 }
170
Paul Stewart63864b62012-11-07 15:10:55 -0800171 void SetRunning(bool running) {
172 manager()->running_ = running;
173 }
174
Paul Stewart75225512012-01-26 22:51:33 -0800175 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
176 return manager->ephemeral_profile_;
177 }
178
Paul Stewart307c2502013-03-23 12:32:10 -0700179 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
180 return manager->profiles_;
181 }
182
Chris Masone6515aab2011-10-12 16:19:09 -0700183 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
184 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700185 FilePath final_path(storage_path());
186 final_path = final_path.Append("test.profile");
187 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
188 storage->set_path(final_path);
189 if (!storage->Open())
190 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800191 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800192 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800193 manager,
194 id,
195 "",
196 false));
197 profile->set_storage(storage.release()); // Passes ownership of "storage".
198 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700199 }
200
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700201 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700202 const string &user_identifier,
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700203 const string &profile_identifier,
204 const string &service_name) {
205 GLib glib;
206 KeyFileStore store(&glib);
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700207 store.set_path(temp_dir->path().Append(
208 base::StringPrintf("%s/%s.profile", user_identifier.c_str(),
209 profile_identifier.c_str())));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700210 return store.Open() &&
211 store.SetString(service_name, "rather", "irrelevant") &&
212 store.Close();
213 }
214
215 Error::Type TestCreateProfile(Manager *manager, const string &name) {
216 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800217 string path;
218 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700219 return error.type();
220 }
221
222 Error::Type TestPopAnyProfile(Manager *manager) {
223 Error error;
224 manager->PopAnyProfile(&error);
225 return error.type();
226 }
227
Paul Stewart307c2502013-03-23 12:32:10 -0700228 Error::Type TestPopAllUserProfiles(Manager *manager) {
229 Error error;
230 manager->PopAllUserProfiles(&error);
231 return error.type();
232 }
233
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700234 Error::Type TestPopProfile(Manager *manager, const string &name) {
235 Error error;
236 manager->PopProfile(name, &error);
237 return error.type();
238 }
239
240 Error::Type TestPushProfile(Manager *manager, const string &name) {
241 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800242 string path;
243 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700244 return error.type();
245 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000246
Paul Stewartf3eced92013-04-17 12:18:22 -0700247 Error::Type TestInsertUserProfile(Manager *manager,
248 const string &name,
249 const string &user_hash) {
250 Error error;
251 string path;
252 manager->InsertUserProfile(name, user_hash, &path, &error);
253 return error.type();
254 }
255
Paul Stewartd2e1c362013-03-03 19:06:07 -0800256 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
257 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700258 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800259 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800260 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200261 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700262 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800263 return profile;
264 }
265
266 void AddMockProfileToManager(Manager *manager) {
267 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700268 }
269
Paul Stewartdfa46052012-06-26 09:44:14 -0700270 void CompleteServiceSort() {
271 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
272 dispatcher()->DispatchPendingEvents();
273 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
274 }
275
Paul Stewart03e29f72013-09-26 00:49:48 -0700276 void RefreshConnectionState() {
277 manager()->RefreshConnectionState();
278 }
279
Paul Stewart49739c02012-08-08 17:24:03 -0700280 RpcIdentifier GetDefaultServiceRpcIdentifier() {
281 return manager()->GetDefaultServiceRpcIdentifier(NULL);
282 }
283
Paul Stewart4d5efb72012-09-17 12:24:34 -0700284 void SetResolver(Resolver *resolver) {
285 manager()->resolver_ = resolver;
286 }
287
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700288 bool SetIgnoredDNSSearchPaths(const string &search_paths, Error *error) {
289 return manager()->SetIgnoredDNSSearchPaths(search_paths, error);
290 }
291
292 bool SetCheckPortalList(const string &check_portal_list, Error *error) {
293 return manager()->SetCheckPortalList(check_portal_list, error);
Paul Stewart4d5efb72012-09-17 12:24:34 -0700294 }
295
296 const string &GetIgnoredDNSSearchPaths() {
297 return manager()->props_.ignored_dns_search_paths;
298 }
299
Paul Stewartd2e1c362013-03-03 19:06:07 -0800300 WiFiServiceRefPtr ReleaseTempMockService() {
301 // Take a reference to hold during this function.
302 WiFiServiceRefPtr temp_service = temp_mock_service_;
303 temp_mock_service_ = NULL;
304 return temp_service;
305 }
306
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700307 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000308 typedef scoped_refptr<MockService> MockServiceRefPtr;
309
Darin Petkova5e07ef2012-07-09 14:27:57 +0200310 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
311 public:
312 ServiceWatcher() {}
313 virtual ~ServiceWatcher() {}
314
315 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
316
317 private:
318 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
319 };
320
Darin Petkov3ec55342012-09-28 14:04:44 +0200321 class TerminationActionTest :
322 public base::SupportsWeakPtr<TerminationActionTest> {
323 public:
324 static const char kActionName[];
325
326 TerminationActionTest() : manager_(NULL) {}
327 virtual ~TerminationActionTest() {}
328
329 MOCK_METHOD1(Done, void(const Error &error));
330
331 void Action() {
332 manager_->TerminationActionComplete("action");
333 }
334
335 void set_manager(Manager *manager) { manager_ = manager; }
336
337 private:
338 Manager *manager_;
339 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
340 };
341
Christopher Wiley1057cd72013-02-28 15:21:29 -0800342 class DestinationVerificationTest :
343 public base::SupportsWeakPtr<DestinationVerificationTest> {
344 public:
345 DestinationVerificationTest() {}
346 virtual ~DestinationVerificationTest() {}
347
348 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
349 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
350 const string &value));
351 private:
352 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
353 };
354
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700355 class DisableTechnologyReplyHandler :
356 public base::SupportsWeakPtr<DisableTechnologyReplyHandler> {
357 public:
358 DisableTechnologyReplyHandler() {}
359 virtual ~DisableTechnologyReplyHandler() {}
360
361 MOCK_METHOD1(ReportResult, void(const Error &));
362
363 private:
364 DISALLOW_COPY_AND_ASSIGN(DisableTechnologyReplyHandler);
365 };
366
Daniel Eratfac09532014-04-17 20:25:59 -0700367 void SetSuspending(bool suspending) {
368 power_manager_->suspending_ = suspending;
Darin Petkovca621542012-07-25 14:25:56 +0200369 }
370
371 void SetPowerManager() {
372 manager()->set_power_manager(power_manager_.release());
373 }
374
Darin Petkov3ec55342012-09-28 14:04:44 +0200375 HookTable *GetTerminationActions() {
376 return &manager()->termination_actions_;
377 }
378
Daniel Erat0818cca2012-12-14 10:16:21 -0800379 void OnSuspendImminent(int suspend_id) {
380 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200381 }
382
Daniel Eratfac09532014-04-17 20:25:59 -0700383 void OnSuspendDone(int suspend_id) {
384 manager()->OnSuspendDone(suspend_id);
385 }
386
Daniel Erat0818cca2012-12-14 10:16:21 -0800387 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
388 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200389 }
390
Paul Stewartbfb82552012-10-24 16:48:48 -0700391 vector<string> EnumerateAvailableServices() {
392 return manager()->EnumerateAvailableServices(NULL);
393 }
394
395 vector<string> EnumerateWatchedServices() {
396 return manager()->EnumerateWatchedServices(NULL);
397 }
398
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000399 MockServiceRefPtr MakeAutoConnectableService() {
400 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
401 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800402 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000403 manager());
Paul Stewart2da34c02013-10-17 15:28:56 -0700404 service->EnableAndRetainAutoConnect();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700405 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000406 return service;
407 }
408
Paul Stewart35eff132013-04-12 12:08:40 -0700409 void SetEapProviderService(const ServiceRefPtr &service) {
410 ethernet_eap_provider_->set_service(service);
411 }
412
Ben Chana55469d2014-01-27 16:35:29 -0800413 NiceMock<MockProxyFactory> proxy_factory_;
Darin Petkovca621542012-07-25 14:25:56 +0200414 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700415 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800416 scoped_ptr<MockDeviceInfo> device_info_;
417
Paul Stewartd2e1c362013-03-03 19:06:07 -0800418 // This service is held for the manager, and given ownership in a mock
419 // function. This ensures that when the Manager takes ownership, there
420 // is only one reference left.
421 scoped_refptr<MockWiFiService> temp_mock_service_;
422
Paul Stewart3c504012013-01-17 17:49:58 -0800423 // These pointers are owned by the manager, and only tracked here for
424 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800425 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700426 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800427 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800428 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700429};
430
Darin Petkov3ec55342012-09-28 14:04:44 +0200431const char ManagerTest::TerminationActionTest::kActionName[] = "action";
432
Paul Stewart22aa71b2011-09-16 12:15:11 -0700433bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700434 if (!manager()->sort_services_task_.IsCancelled()) {
435 manager()->SortServicesTask();
436 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700437 return (svc0.get() == manager()->services_[0].get() &&
438 svc1.get() == manager()->services_[1].get());
439}
440
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700441void SetErrorPermissionDenied(Error *error) {
442 error->Populate(Error::kPermissionDenied);
443}
444
Arman Uguray2f352e62013-08-28 19:12:53 -0700445void SetErrorSuccess(Error *error) {
446 error->Reset();
447}
448
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700449TEST_F(ManagerTest, Contains) {
Ben Chan923a5022013-09-20 11:23:23 -0700450 EXPECT_TRUE(manager()->store().Contains(kStateProperty));
mukesh agrawalde29fa82011-09-16 16:16:36 -0700451 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700452}
453
Chris Masone9be4a9d2011-05-16 15:44:09 -0700454TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700455 ON_CALL(*mock_devices_[0].get(), technology())
456 .WillByDefault(Return(Technology::kEthernet));
457 ON_CALL(*mock_devices_[1].get(), technology())
458 .WillByDefault(Return(Technology::kWifi));
459 ON_CALL(*mock_devices_[2].get(), technology())
460 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700461
Paul Stewart22aa71b2011-09-16 12:15:11 -0700462 manager()->RegisterDevice(mock_devices_[0]);
463 manager()->RegisterDevice(mock_devices_[1]);
464 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700465
Paul Stewart22aa71b2011-09-16 12:15:11 -0700466 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
467 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
468 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700469}
470
Paul Stewarta41e38d2011-11-11 07:47:29 -0800471TEST_F(ManagerTest, DeviceRegistrationAndStart) {
472 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500473 mock_devices_[0]->enabled_persistent_ = true;
474 mock_devices_[1]->enabled_persistent_ = false;
475 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800476 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500477 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800478 .Times(0);
479 manager()->RegisterDevice(mock_devices_[0]);
480 manager()->RegisterDevice(mock_devices_[1]);
481}
482
483TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800484 MockProfile *profile =
485 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800486 DeviceRefPtr device_ref(mock_devices_[0].get());
487 AdoptProfile(manager(), profile); // Passes ownership.
488 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200489 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800490 manager()->RegisterDevice(mock_devices_[0]);
491}
492
Chris Masone9be4a9d2011-05-16 15:44:09 -0700493TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700494 ON_CALL(*mock_devices_[0].get(), technology())
495 .WillByDefault(Return(Technology::kEthernet));
496 ON_CALL(*mock_devices_[1].get(), technology())
497 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700498
Gaurav Shah435de2c2011-11-17 19:01:07 -0800499 manager()->RegisterDevice(mock_devices_[0]);
500 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700501
Paul Stewart22aa71b2011-09-16 12:15:11 -0700502 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
503 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700504
Thieu Le5133b712013-02-19 14:47:21 -0800505 MockProfile *profile =
506 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700507 AdoptProfile(manager(), profile); // Passes ownership.
508
Eric Shienbrood9a245532012-03-07 14:20:39 -0500509 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700510 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800511 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700512 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700513
Eric Shienbrood9a245532012-03-07 14:20:39 -0500514 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700515 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800516 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700517 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700518}
519
520TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700521 // It's much easier and safer to use a real GLib for this test.
522 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700523 Manager manager(control_interface(),
524 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800525 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700526 &glib,
527 run_path(),
528 storage_path(),
529 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700530 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
531 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700532 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700533
Chris Masone9be4a9d2011-05-16 15:44:09 -0700534 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700535 new NiceMock<MockService>(control_interface(),
536 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800537 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700538 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700539 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700540 new NiceMock<MockService>(control_interface(),
541 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800542 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700543 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700544
Darin Petkov457728b2013-01-09 09:49:08 +0100545 string service1_name(mock_service->unique_name());
546 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700547
548 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
549 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700550 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700551 .WillRepeatedly(Return(service2_name));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700552 // TODO(quiche): make this EXPECT_CALL work (crbug.com/203247)
Chris Masone9d779932011-08-25 16:33:41 -0700553 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
Ben Chan923a5022013-09-20 11:23:23 -0700554 // EmitRpcIdentifierArrayChanged(kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700555
Chris Masone9d779932011-08-25 16:33:41 -0700556 manager.RegisterService(mock_service);
557 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700558
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800559 Error error;
560 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700561 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700562 EXPECT_EQ(2, ids.size());
563 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
564 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700565
Chris Masone9d779932011-08-25 16:33:41 -0700566 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
567 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
568
569 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700570}
571
Chris Masone6515aab2011-10-12 16:19:09 -0700572TEST_F(ManagerTest, RegisterKnownService) {
573 // It's much easier and safer to use a real GLib for this test.
574 GLib glib;
575 Manager manager(control_interface(),
576 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800577 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700578 &glib,
579 run_path(),
580 storage_path(),
581 string());
582 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
583 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700584 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700585 {
586 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
587 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800588 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700589 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700590 ASSERT_TRUE(profile->AdoptService(service1));
591 ASSERT_TRUE(profile->ContainsService(service1));
592 } // Force destruction of service1.
593
594 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
595 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800596 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700597 &manager));
598 manager.RegisterService(service2);
599 EXPECT_EQ(service2->profile().get(), profile.get());
600 manager.Stop();
601}
602
603TEST_F(ManagerTest, RegisterUnknownService) {
604 // It's much easier and safer to use a real GLib for this test.
605 GLib glib;
606 Manager manager(control_interface(),
607 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800608 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700609 &glib,
610 run_path(),
611 storage_path(),
612 string());
613 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
614 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700615 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700616 {
617 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
618 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800619 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700620 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700621 ASSERT_TRUE(profile->AdoptService(service1));
622 ASSERT_TRUE(profile->ContainsService(service1));
623 } // Force destruction of service1.
624 scoped_refptr<MockService> mock_service2(
625 new NiceMock<MockService>(control_interface(),
626 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800627 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700628 &manager));
629 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100630 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700631 manager.RegisterService(mock_service2);
632 EXPECT_NE(mock_service2->profile().get(), profile.get());
633 manager.Stop();
634}
635
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000636TEST_F(ManagerTest, DeregisterUnregisteredService) {
637 // WiFi assumes that it can deregister a service that is not
638 // registered. (E.g. a hidden service can be deregistered when it
639 // loses its last endpoint, and again when WiFi is Stop()-ed.)
640 //
641 // So test that doing so doesn't cause a crash.
642 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
643 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800644 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000645 manager());
646 manager()->DeregisterService(service);
647}
648
Chris Masonea8a2c252011-06-27 22:16:30 -0700649TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700650 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700651 map<string, ::DBus::Variant> props;
652 Error error(Error::kInvalidProperty, "");
653 {
654 ::DBus::Error dbus_error;
655 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700656 manager()->mutable_store()->SetStringProperty(
Ben Chan923a5022013-09-20 11:23:23 -0700657 kCheckPortalListProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700658 expected,
659 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700660 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700661 ASSERT_FALSE(props.find(kCheckPortalListProperty) == props.end());
662 EXPECT_EQ(props[kCheckPortalListProperty].reader().get_string(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700663 expected);
664 }
665 {
666 ::DBus::Error dbus_error;
667 bool expected = true;
Ben Chan923a5022013-09-20 11:23:23 -0700668 manager()->mutable_store()->SetBoolProperty(kOfflineModeProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700669 expected,
670 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700671 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700672 ASSERT_FALSE(props.find(kOfflineModeProperty) == props.end());
673 EXPECT_EQ(props[kOfflineModeProperty].reader().get_bool(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700674 expected);
675 }
676}
677
Chris Masone3c3f6a12011-07-01 10:01:41 -0700678TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700679 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800680 manager()->RegisterDevice(mock_devices_[0]);
681 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700682 {
683 map<string, ::DBus::Variant> props;
684 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700685 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700686 ASSERT_FALSE(props.find(kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700687 vector < ::DBus::Path> devices =
Ben Chan923a5022013-09-20 11:23:23 -0700688 props[kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700689 EXPECT_EQ(2, devices.size());
690 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700691}
692
mukesh agrawal2366eed2012-03-20 18:21:50 -0700693TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700694 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700695 map<string, ::DBus::Variant> props;
696 ::DBus::Error dbus_error;
697 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
698 map<string, ::DBus::Variant>::const_iterator prop =
Ben Chan923a5022013-09-20 11:23:23 -0700699 props.find(kServicesProperty);
mukesh agrawal2366eed2012-03-20 18:21:50 -0700700 ASSERT_FALSE(prop == props.end());
701 const ::DBus::Variant &variant = prop->second;
702 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
703}
704
Chris Masone6791a432011-07-12 13:23:19 -0700705TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700706 Manager manager(control_interface(),
707 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800708 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700709 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700710 run_path(),
711 storage_path(),
712 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700713 scoped_refptr<MockService> s2(new MockService(control_interface(),
714 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800715 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700716 &manager));
717 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700718 {
Chris Masone6515aab2011-10-12 16:19:09 -0700719 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700720 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800721 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700722 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700723 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700724 .WillRepeatedly(Return(true));
725 EXPECT_CALL(*storage, Flush())
726 .Times(AnyNumber())
727 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700728 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700729 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700730 }
Chris Masone6515aab2011-10-12 16:19:09 -0700731 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800732 ProfileRefPtr profile(
733 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700734 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700735
Chris Masone6515aab2011-10-12 16:19:09 -0700736 // Now, move the Service |s2| to another profile.
737 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
738 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700739
740 // Force destruction of the original Profile, to ensure that the Service
741 // is kept alive and populated with data.
742 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700743 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700744 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700745}
746
Paul Stewart7f61e522012-03-22 11:13:45 -0700747TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
748 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800749 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700750 const string kProfileName("profile0");
751 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
752 .WillRepeatedly(Return(kProfileName));
753 AdoptProfile(manager(), mock_profile);
754
755 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
756 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
757 EXPECT_EQ(mock_profile.get(), profile.get());
758}
759
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800760TEST_F(ManagerTest, SetProfileForService) {
761 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800762 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800763 string profile_name0("profile0");
764 EXPECT_CALL(*profile0, GetRpcIdentifier())
765 .WillRepeatedly(Return(profile_name0));
766 AdoptProfile(manager(), profile0);
767 scoped_refptr<MockService> service(new MockService(control_interface(),
768 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800769 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800770 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700771 EXPECT_FALSE(manager()->HasService(service));
772 {
773 Error error;
774 EXPECT_CALL(*profile0, AdoptService(_))
775 .WillOnce(Return(true));
776 // Expect that setting the profile of a service that does not already
777 // have one assigned does not cause a crash.
778 manager()->SetProfileForService(service, "profile0", &error);
779 EXPECT_TRUE(error.IsSuccess());
780 }
781
782 // The service should be registered as a side-effect of the profile being
783 // set for this service.
784 EXPECT_TRUE(manager()->HasService(service));
785
786 // Since we have mocked Profile::AdoptServie() above, the service's
787 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800788 service->set_profile(profile0);
789
790 {
791 Error error;
792 manager()->SetProfileForService(service, "foo", &error);
793 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700794 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800795 }
796
797 {
798 Error error;
799 manager()->SetProfileForService(service, profile_name0, &error);
800 EXPECT_EQ(Error::kInvalidArguments, error.type());
801 EXPECT_EQ("Service is already connected to this profile", error.message());
802 }
803
804 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800805 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800806 string profile_name1("profile1");
807 EXPECT_CALL(*profile1, GetRpcIdentifier())
808 .WillRepeatedly(Return(profile_name1));
809 AdoptProfile(manager(), profile1);
810
811 {
812 Error error;
813 EXPECT_CALL(*profile1, AdoptService(_))
814 .WillOnce(Return(true));
815 EXPECT_CALL(*profile0, AbandonService(_))
816 .WillOnce(Return(true));
817 manager()->SetProfileForService(service, profile_name1, &error);
818 EXPECT_TRUE(error.IsSuccess());
819 }
820}
821
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700822TEST_F(ManagerTest, CreateProfile) {
823 // It's much easier to use real Glib here since we want the storage
824 // side-effects.
825 GLib glib;
826 ScopedTempDir temp_dir;
827 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
828
829 Manager manager(control_interface(),
830 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800831 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700832 &glib,
833 run_path(),
834 storage_path(),
835 temp_dir.path().value());
836
837 // Invalid name should be rejected.
838 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
839
Paul Stewartd0a3b812012-03-28 22:48:22 -0700840 // A profile with invalid characters in it should similarly be rejected.
841 EXPECT_EQ(Error::kInvalidArguments,
842 TestCreateProfile(&manager, "valid_profile"));
843
844 // We should be able to create a machine profile.
845 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700846
Gary Morainb672d352012-04-25 09:19:06 -0700847 // We should succeed in creating a valid user profile. Verify the returned
848 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700849 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700850 {
851 Error error;
852 string path;
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700853 ASSERT_TRUE(base::CreateDirectory(temp_dir.path().Append("user")));
Gary Morainb672d352012-04-25 09:19:06 -0700854 manager.CreateProfile(kProfile, &path, &error);
855 EXPECT_EQ(Error::kSuccess, error.type());
856 EXPECT_EQ("/profile_rpc", path);
857 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700858
859 // We should fail in creating it a second time (already exists).
860 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
861}
862
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700863// We receive PopProfile when a user logs out, and it should always trigger a
864// MemoryLog Clear() call.
865TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
866 GLib glib;
867 ScopedTempDir temp_dir;
868 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
869 Manager manager(control_interface(),
870 dispatcher(),
871 metrics(),
872 &glib,
873 run_path(),
874 storage_path(),
875 temp_dir.path().value());
876 const char kProfile0[] = "~user/profile0";
877 const char kPurgedMessage[] = "This message should be purged";
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700878
879 ASSERT_TRUE(base::CreateDirectory(temp_dir.path().Append("user")));
880
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700881 // Create a profile and push it on the stack, leave one uncreated
882 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
883 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
884
885 // Popping a profile which isn't on top should still clear the log.
886 LOG(INFO) << kPurgedMessage;
887 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
888 kPurgedMessage));
889 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
890 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
891 kPurgedMessage));
892
893 // Popping an invalid profile name should do the same thing.
894 LOG(INFO) << kPurgedMessage;
895 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
896 kPurgedMessage));
897 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
898 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
899 kPurgedMessage));
900
901 // Successful pops also purge the message log.
902 LOG(INFO) << kPurgedMessage;
903 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
904 kPurgedMessage));
905 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
906 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
907 kPurgedMessage));
908}
909
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700910TEST_F(ManagerTest, PushPopProfile) {
911 // It's much easier to use real Glib in creating a Manager for this
912 // test here since we want the storage side-effects.
913 GLib glib;
914 ScopedTempDir temp_dir;
915 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
916 Manager manager(control_interface(),
917 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800918 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700919 &glib,
920 run_path(),
921 storage_path(),
922 temp_dir.path().value());
mukesh agrawal92496a42014-04-08 16:04:43 -0700923 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700924
925 // Pushing an invalid profile should fail.
926 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
927
mukesh agrawal92496a42014-04-08 16:04:43 -0700928 // Create and push a default profile. Should succeed.
929 const char kDefaultProfile0[] = "default";
930 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kDefaultProfile0));
931 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kDefaultProfile0));
932 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kDefaultProfile0));
933
934 // Pushing a default profile that does not exist on disk will _not_
935 // fail, because we'll use temporary storage for it.
936 const char kMissingDefaultProfile[] = "missingdefault";
937 EXPECT_EQ(Error::kSuccess,
938 TestPushProfile(&manager, kMissingDefaultProfile));
939 EXPECT_EQ(1, profiles.size());
940 EXPECT_EQ(Error::kSuccess,
941 TestPopProfile(&manager, kMissingDefaultProfile));
942 EXPECT_EQ(0, profiles.size());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700943
944 const char kProfile0[] = "~user/profile0";
945 const char kProfile1[] = "~user/profile1";
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700946 ASSERT_TRUE(base::CreateDirectory(temp_dir.path().Append("user")));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700947
948 // Create a couple of profiles.
949 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
950 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
951
952 // Push these profiles on the stack.
953 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
954 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
955
956 // Pushing a profile a second time should fail.
957 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
958 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
959
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800960 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700961 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800962 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700963
964 // Make sure a profile name that doesn't exist fails.
965 const char kProfile2Id[] = "profile2";
966 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
967 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
968
969 // Create a new service, with a specific storage name.
970 scoped_refptr<MockService> service(
971 new NiceMock<MockService>(control_interface(),
972 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800973 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700974 &manager));
975 const char kServiceName[] = "service_storage_name";
976 EXPECT_CALL(*service.get(), GetStorageIdentifier())
977 .WillRepeatedly(Return(kServiceName));
978 EXPECT_CALL(*service.get(), Load(_))
979 .WillRepeatedly(Return(true));
980
981 // Add this service to the manager -- it should end up in the ephemeral
982 // profile.
983 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800984 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700985
986 // Create storage for a profile that contains the service storage name.
mukesh agrawal0a59a5a2014-04-24 19:10:46 -0700987 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, "user", kProfile2Id,
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700988 kServiceName));
989
990 // When we push the profile, the service should move away from the
991 // ephemeral profile to this new profile since it has an entry for
992 // this service.
Paul Stewart2eee6132014-05-09 13:33:26 -0700993 EXPECT_CALL(*service, ClearExplicitlyDisconnected());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700994 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800995 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700996 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
997
998 // Insert another profile that should supersede ownership of the service.
999 const char kProfile3Id[] = "profile3";
1000 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
mukesh agrawal0a59a5a2014-04-24 19:10:46 -07001001 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, "user", kProfile3Id,
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001002 kServiceName));
Paul Stewart2eee6132014-05-09 13:33:26 -07001003 // We don't verify this expectation inline, since this would clear other
1004 // recurring expectations on the service.
1005 EXPECT_CALL(*service, ClearExplicitlyDisconnected());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001006 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
1007 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
1008
1009 // Popping an invalid profile name should fail.
1010 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
1011
1012 // Popping an profile that is not at the top of the stack should fail.
1013 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
1014
1015 // Popping the top profile should succeed.
Paul Stewart2eee6132014-05-09 13:33:26 -07001016 EXPECT_CALL(*service, ClearExplicitlyDisconnected());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001017 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
1018
1019 // Moreover the service should have switched profiles to profile 2.
1020 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
1021
1022 // Popping the top profile should succeed.
Paul Stewart2eee6132014-05-09 13:33:26 -07001023 EXPECT_CALL(*service, ClearExplicitlyDisconnected());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001024 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1025
1026 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -08001027 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001028
mukesh agrawal92496a42014-04-08 16:04:43 -07001029 // Pop the remaining two profiles off the stack.
Paul Stewart2eee6132014-05-09 13:33:26 -07001030 EXPECT_CALL(*service, ClearExplicitlyDisconnected()).Times(2);
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001031 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1032 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
Paul Stewart2eee6132014-05-09 13:33:26 -07001033 Mock::VerifyAndClearExpectations(service);
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001034
1035 // Next pop should fail with "stack is empty".
1036 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -07001037
1038 const char kMachineProfile0[] = "machineprofile0";
1039 const char kMachineProfile1[] = "machineprofile1";
1040 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
1041 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
1042
1043 // Should be able to push a machine profile.
1044 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
1045
1046 // Should be able to push a user profile atop a machine profile.
1047 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1048
1049 // Pushing a system-wide profile on top of a user profile should fail.
1050 EXPECT_EQ(Error::kInvalidArguments,
1051 TestPushProfile(&manager, kMachineProfile1));
1052
1053 // However if we pop the user profile, we should be able stack another
1054 // machine profile on.
1055 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1056 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001057
1058 // Add two user profiles to the top of the stack.
1059 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1060 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001061 EXPECT_EQ(4, profiles.size());
1062
1063 // PopAllUserProfiles should remove both user profiles, leaving the two
1064 // machine profiles.
1065 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1066 EXPECT_EQ(2, profiles.size());
1067 EXPECT_TRUE(profiles[0]->GetUser().empty());
1068 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001069
1070 // Use InsertUserProfile() instead. Although a machine profile is valid
1071 // in this state, it cannot be added via InsertUserProfile.
1072 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1073 EXPECT_EQ(Error::kInvalidArguments,
1074 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1075 const char kUserHash0[] = "userhash0";
1076 const char kUserHash1[] = "userhash1";
1077 EXPECT_EQ(Error::kSuccess,
1078 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1079 EXPECT_EQ(Error::kSuccess,
1080 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1081 EXPECT_EQ(3, profiles.size());
1082 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1083 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001084}
1085
Paul Stewarte73d05c2012-03-29 16:26:05 -07001086TEST_F(ManagerTest, RemoveProfile) {
1087 // It's much easier to use real Glib in creating a Manager for this
1088 // test here since we want the storage side-effects.
1089 GLib glib;
1090 ScopedTempDir temp_dir;
1091 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1092 Manager manager(control_interface(),
1093 dispatcher(),
1094 metrics(),
1095 &glib,
1096 run_path(),
1097 storage_path(),
1098 temp_dir.path().value());
1099
1100 const char kProfile0[] = "profile0";
1101 FilePath profile_path(
1102 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1103
1104 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
Ben Chana0ddf462014-02-06 11:32:42 -08001105 ASSERT_TRUE(base::PathExists(profile_path));
Paul Stewarte73d05c2012-03-29 16:26:05 -07001106
1107 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1108
1109 // Remove should fail since the profile is still on the stack.
1110 {
1111 Error error;
1112 manager.RemoveProfile(kProfile0, &error);
1113 EXPECT_EQ(Error::kInvalidArguments, error.type());
1114 }
1115
1116 // Profile path should still exist.
Ben Chana0ddf462014-02-06 11:32:42 -08001117 EXPECT_TRUE(base::PathExists(profile_path));
Paul Stewarte73d05c2012-03-29 16:26:05 -07001118
1119 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1120
1121 // This should succeed now that the profile is off the stack.
1122 {
1123 Error error;
1124 manager.RemoveProfile(kProfile0, &error);
1125 EXPECT_EQ(Error::kSuccess, error.type());
1126 }
1127
1128 // Profile path should no longer exist.
Ben Chana0ddf462014-02-06 11:32:42 -08001129 EXPECT_FALSE(base::PathExists(profile_path));
Paul Stewarte73d05c2012-03-29 16:26:05 -07001130
Ben Chana0ddf462014-02-06 11:32:42 -08001131 // Another remove succeeds, due to a foible in base::DeleteFile --
Paul Stewarte73d05c2012-03-29 16:26:05 -07001132 // it is not an error to delete a file that does not exist.
1133 {
1134 Error error;
1135 manager.RemoveProfile(kProfile0, &error);
1136 EXPECT_EQ(Error::kSuccess, error.type());
1137 }
1138
1139 // Let's create an error case that will "work". Create a non-empty
1140 // directory in the place of the profile pathname.
Ben Chana0ddf462014-02-06 11:32:42 -08001141 ASSERT_TRUE(base::CreateDirectory(profile_path.Append("foo")));
Paul Stewarte73d05c2012-03-29 16:26:05 -07001142 {
1143 Error error;
1144 manager.RemoveProfile(kProfile0, &error);
1145 EXPECT_EQ(Error::kOperationFailed, error.type());
1146 }
1147}
1148
Paul Stewartd3d03882013-08-29 15:43:42 -07001149TEST_F(ManagerTest, RemoveService) {
1150 MockServiceRefPtr mock_service(
1151 new NiceMock<MockService>(control_interface(),
1152 dispatcher(),
1153 metrics(),
1154 manager()));
1155
1156 // Used in expectations which cannot accept a mock refptr.
1157 const ServiceRefPtr &service = mock_service;
1158
1159 manager()->RegisterService(service);
1160 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1161
1162 scoped_refptr<MockProfile> profile(
1163 new StrictMock<MockProfile>(
1164 control_interface(), metrics(), manager(), ""));
1165 AdoptProfile(manager(), profile);
1166
1167 // If service is ephemeral, it should be unloaded and left ephemeral.
1168 EXPECT_CALL(*profile, AbandonService(service)).Times(0);
1169 EXPECT_CALL(*profile, ConfigureService(service)).Times(0);
1170 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(false));
1171 manager()->RemoveService(service);
1172 Mock::VerifyAndClearExpectations(mock_service);
1173 Mock::VerifyAndClearExpectations(profile);
1174 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1175 EXPECT_TRUE(manager()->HasService(service)); // Since Unload() was false.
1176
1177 // If service is not ephemeral and the Manager finds a profile to assign
1178 // the service to, the service should be re-parented. Note that since we
1179 // are using a MockProfile, ConfigureService() never actually changes the
1180 // Service's profile.
1181 service->set_profile(profile);
1182 EXPECT_CALL(*profile, AbandonService(service));
1183 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(true));
1184 EXPECT_CALL(*mock_service, Unload()).Times(0);
1185 manager()->RemoveService(service);
1186 Mock::VerifyAndClearExpectations(mock_service);
1187 Mock::VerifyAndClearExpectations(profile);
1188 EXPECT_TRUE(manager()->HasService(service));
1189 EXPECT_EQ(profile.get(), service->profile().get());
1190
1191 // If service becomes ephemeral since there is no profile to support it,
1192 // it should be unloaded.
1193 EXPECT_CALL(*profile, AbandonService(service));
1194 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(false));
1195 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(true));
1196 manager()->RemoveService(service);
1197 EXPECT_FALSE(manager()->HasService(service));
1198}
1199
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001200TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1201 // It's much easier to use real Glib in creating a Manager for this
1202 // test here since we want the storage side-effects.
1203 GLib glib;
1204 ScopedTempDir temp_dir;
1205 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1206 Manager manager(control_interface(),
1207 dispatcher(),
1208 metrics(),
1209 &glib,
1210 run_path(),
1211 storage_path(),
1212 temp_dir.path().value());
1213
1214 const char kProfile0[] = "profile0";
1215 FilePath profile_path(
1216 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1217
1218 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
Ben Chana0ddf462014-02-06 11:32:42 -08001219 ASSERT_TRUE(base::PathExists(profile_path));
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001220 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1221
1222 // Ensure that even if the backing filestore is removed, we still can't
1223 // create a profile twice.
Ben Chana0ddf462014-02-06 11:32:42 -08001224 ASSERT_TRUE(base::DeleteFile(profile_path, false));
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001225 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1226}
1227
Paul Stewart75225512012-01-26 22:51:33 -08001228TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1229 MockServiceRefPtr s_not_in_profile(
1230 new NiceMock<MockService>(control_interface(),
1231 dispatcher(),
1232 metrics(),
1233 manager()));
1234 MockServiceRefPtr s_not_in_group(
1235 new NiceMock<MockService>(control_interface(),
1236 dispatcher(),
1237 metrics(),
1238 manager()));
1239 MockServiceRefPtr s_configure_fail(
1240 new NiceMock<MockService>(control_interface(),
1241 dispatcher(),
1242 metrics(),
1243 manager()));
1244 MockServiceRefPtr s_configure_succeed(
1245 new NiceMock<MockService>(control_interface(),
1246 dispatcher(),
1247 metrics(),
1248 manager()));
1249
1250 string entry_name("entry_name");
1251 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1252 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1253 .WillRepeatedly(Return("not_entry_name"));
1254 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1255 .WillRepeatedly(Return(entry_name));
1256 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1257 .WillRepeatedly(Return(entry_name));
1258
1259 manager()->RegisterService(s_not_in_profile);
1260 manager()->RegisterService(s_not_in_group);
1261 manager()->RegisterService(s_configure_fail);
1262 manager()->RegisterService(s_configure_succeed);
1263
1264 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001265 new StrictMock<MockProfile>(
1266 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001267 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001268 new StrictMock<MockProfile>(
1269 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001270
1271 s_not_in_group->set_profile(profile1);
1272 s_configure_fail->set_profile(profile1);
1273 s_configure_succeed->set_profile(profile1);
1274
1275 AdoptProfile(manager(), profile0);
1276 AdoptProfile(manager(), profile1);
1277
1278 // No services are a member of this profile.
1279 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1280
1281 // No services that are members of this profile have this entry name.
1282 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1283
1284 // Only services that are members of the profile and group will be abandoned.
1285 EXPECT_CALL(*profile1.get(),
1286 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1287 EXPECT_CALL(*profile1.get(),
1288 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1289 EXPECT_CALL(*profile1.get(),
1290 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1291 .WillOnce(Return(true));
1292 EXPECT_CALL(*profile1.get(),
1293 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1294 .WillOnce(Return(true));
1295
1296 // Never allow services to re-join profile1.
1297 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1298 .WillRepeatedly(Return(false));
1299
1300 // Only allow one of the members of the profile and group to successfully
1301 // join profile0.
1302 EXPECT_CALL(*profile0.get(),
1303 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1304 EXPECT_CALL(*profile0.get(),
1305 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1306 EXPECT_CALL(*profile0.get(),
1307 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1308 .WillOnce(Return(false));
1309 EXPECT_CALL(*profile0.get(),
1310 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1311 .WillOnce(Return(true));
1312
1313 // Expect the failed-to-configure service to have Unload() called on it.
1314 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1315 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1316 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1317 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1318
1319 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1320
1321 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1322 EXPECT_EQ(profile1, s_not_in_group->profile());
1323 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1324
1325 // Since we are using a MockProfile, the profile does not actually change,
1326 // since ConfigureService was not actually called on the service.
1327 EXPECT_EQ(profile1, s_configure_succeed->profile());
1328}
1329
Paul Stewart65512e12012-03-26 18:01:08 -07001330TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1331 MockServiceRefPtr s_will_remove0(
1332 new NiceMock<MockService>(control_interface(),
1333 dispatcher(),
1334 metrics(),
1335 manager()));
1336 MockServiceRefPtr s_will_remove1(
1337 new NiceMock<MockService>(control_interface(),
1338 dispatcher(),
1339 metrics(),
1340 manager()));
1341 MockServiceRefPtr s_will_not_remove0(
1342 new NiceMock<MockService>(control_interface(),
1343 dispatcher(),
1344 metrics(),
1345 manager()));
1346 MockServiceRefPtr s_will_not_remove1(
1347 new NiceMock<MockService>(control_interface(),
1348 dispatcher(),
1349 metrics(),
1350 manager()));
1351
1352 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1353 .Times(4); // Once for each registration.
1354
1355 string entry_name("entry_name");
1356 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1357 .WillRepeatedly(Return(entry_name));
1358 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1359 .WillRepeatedly(Return(entry_name));
1360 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1361 .WillRepeatedly(Return(entry_name));
1362 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1363 .WillRepeatedly(Return(entry_name));
1364
1365 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001366 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001367 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001368 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001369 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001370 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001371 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001372 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001373
1374 // One for each service added above.
1375 ASSERT_EQ(4, manager()->services_.size());
1376
1377 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001378 new StrictMock<MockProfile>(
1379 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001380
1381 s_will_remove0->set_profile(profile);
1382 s_will_remove1->set_profile(profile);
1383 s_will_not_remove0->set_profile(profile);
1384 s_will_not_remove1->set_profile(profile);
1385
1386 AdoptProfile(manager(), profile);
1387
1388 // Deny any of the services re-entry to the profile.
1389 EXPECT_CALL(*profile, ConfigureService(_))
1390 .WillRepeatedly(Return(false));
1391
1392 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1393 .WillOnce(Return(true));
1394 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1395 .WillOnce(Return(true));
1396 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1397 .WillOnce(Return(true));
1398 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1399 .WillOnce(Return(true));
1400
1401 EXPECT_CALL(*s_will_remove0, Unload())
1402 .WillOnce(Return(true));
1403 EXPECT_CALL(*s_will_remove1, Unload())
1404 .WillOnce(Return(true));
1405 EXPECT_CALL(*s_will_not_remove0, Unload())
1406 .WillOnce(Return(false));
1407 EXPECT_CALL(*s_will_not_remove1, Unload())
1408 .WillOnce(Return(false));
1409
1410
1411 // This will cause all the profiles to be unloaded.
1412 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1413
1414 // 2 of the 4 services added above should have been unregistered and
1415 // removed, leaving 2.
1416 EXPECT_EQ(2, manager()->services_.size());
1417 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1418 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1419}
1420
1421TEST_F(ManagerTest, PopProfileWithUnload) {
1422 MockServiceRefPtr s_will_remove0(
1423 new NiceMock<MockService>(control_interface(),
1424 dispatcher(),
1425 metrics(),
1426 manager()));
1427 MockServiceRefPtr s_will_remove1(
1428 new NiceMock<MockService>(control_interface(),
1429 dispatcher(),
1430 metrics(),
1431 manager()));
1432 MockServiceRefPtr s_will_not_remove0(
1433 new NiceMock<MockService>(control_interface(),
1434 dispatcher(),
1435 metrics(),
1436 manager()));
1437 MockServiceRefPtr s_will_not_remove1(
1438 new NiceMock<MockService>(control_interface(),
1439 dispatcher(),
1440 metrics(),
1441 manager()));
1442
1443 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1444 .Times(5); // Once for each registration, and one after profile pop.
1445
1446 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001447 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001448 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001449 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001450 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001451 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001452 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001453 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001454
1455 // One for each service added above.
1456 ASSERT_EQ(4, manager()->services_.size());
1457
1458 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001459 new StrictMock<MockProfile>(
1460 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001461 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001462 new StrictMock<MockProfile>(
1463 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001464
1465 s_will_remove0->set_profile(profile1);
1466 s_will_remove1->set_profile(profile1);
1467 s_will_not_remove0->set_profile(profile1);
1468 s_will_not_remove1->set_profile(profile1);
1469
1470 AdoptProfile(manager(), profile0);
1471 AdoptProfile(manager(), profile1);
1472
1473 // Deny any of the services entry to profile0, so they will all be unloaded.
1474 EXPECT_CALL(*profile0, ConfigureService(_))
1475 .WillRepeatedly(Return(false));
1476
1477 EXPECT_CALL(*s_will_remove0, Unload())
1478 .WillOnce(Return(true));
1479 EXPECT_CALL(*s_will_remove1, Unload())
1480 .WillOnce(Return(true));
1481 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001482 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001483 EXPECT_CALL(*s_will_not_remove1, Unload())
1484 .WillOnce(Return(false));
1485
Philipp Neubeck79173602012-11-13 21:10:09 +01001486 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1487 // profile list.
1488 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1489 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1490
Paul Stewart65512e12012-03-26 18:01:08 -07001491 // This will pop profile1, which should cause all our profiles to unload.
1492 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001493 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001494
1495 // 2 of the 4 services added above should have been unregistered and
1496 // removed, leaving 2.
1497 EXPECT_EQ(2, manager()->services_.size());
1498 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1499 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001500
1501 // Expect the unloaded services to lose their profile reference.
1502 EXPECT_FALSE(s_will_remove0->profile());
1503 EXPECT_FALSE(s_will_remove1->profile());
1504
1505 // If we explicitly deregister a service, the effect should be the same
1506 // with respect to the profile reference.
1507 ASSERT_TRUE(s_will_not_remove0->profile());
1508 manager()->DeregisterService(s_will_not_remove0);
1509 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001510}
1511
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001512TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001513 {
1514 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001515 ::DBus::Variant offline_mode;
1516 offline_mode.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001517 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -07001518 kOfflineModeProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001519 offline_mode,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001520 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001521 }
1522 {
1523 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001524 ::DBus::Variant country;
1525 country.writer().append_string("a_country");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001526 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -07001527 kCountryProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001528 country,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001529 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001530 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001531 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001532 {
1533 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001534 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -07001535 kCountryProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001536 PropertyStoreTest::kBoolV,
1537 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001538 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001539 }
1540 {
1541 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001542 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -07001543 kOfflineModeProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001544 PropertyStoreTest::kStringV,
1545 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001546 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001547 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001548 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001549 {
1550 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001551 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001552 manager()->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -07001553 kEnabledTechnologiesProperty,
Chris Masonea8a2c252011-06-27 22:16:30 -07001554 PropertyStoreTest::kStringsV,
1555 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001556 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001557 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001558}
1559
mukesh agrawal32399322011-09-01 10:53:43 -07001560TEST_F(ManagerTest, RequestScan) {
1561 {
1562 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001563 manager()->RegisterDevice(mock_devices_[0].get());
1564 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001565 EXPECT_CALL(*mock_devices_[0], technology())
1566 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001567 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _, _));
Joshua Krollda798622012-06-05 12:30:48 -07001568 EXPECT_CALL(*mock_devices_[1], technology())
1569 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001570 EXPECT_CALL(*mock_devices_[1], Scan(_, _, _)).Times(0);
Peter Qiue783f1c2014-05-02 11:42:33 -07001571 EXPECT_CALL(*metrics(), NotifyUserInitiatedEvent(
1572 Metrics::kUserInitiatedEventWifiScan)).Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001573 manager()->RequestScan(Device::kFullScan, kTypeWifi, &error);
Peter Qiue783f1c2014-05-02 11:42:33 -07001574 manager()->DeregisterDevice(mock_devices_[0].get());
1575 manager()->DeregisterDevice(mock_devices_[1].get());
1576 Mock::VerifyAndClearExpectations(mock_devices_[0]);
1577 Mock::VerifyAndClearExpectations(mock_devices_[1]);
1578
1579 manager()->RegisterDevice(mock_devices_[0].get());
1580 EXPECT_CALL(*mock_devices_[0], technology())
1581 .WillRepeatedly(Return(Technology::kWifi));
1582 EXPECT_CALL(*metrics(), NotifyUserInitiatedEvent(
1583 Metrics::kUserInitiatedEventWifiScan)).Times(1);
1584 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _, _));
1585 manager()->RequestScan(Device::kFullScan, kTypeWifi, &error);
1586 manager()->DeregisterDevice(mock_devices_[0].get());
1587 Mock::VerifyAndClearExpectations(mock_devices_[0]);
1588
1589 manager()->RegisterDevice(mock_devices_[0].get());
1590 EXPECT_CALL(*mock_devices_[0], technology())
1591 .WillRepeatedly(Return(Technology::kUnknown));
1592 EXPECT_CALL(*metrics(), NotifyUserInitiatedEvent(
1593 Metrics::kUserInitiatedEventWifiScan)).Times(0);
1594 EXPECT_CALL(*mock_devices_[0], Scan(_, _, _)).Times(0);
1595 manager()->RequestScan(Device::kFullScan, kTypeWifi, &error);
1596 manager()->DeregisterDevice(mock_devices_[0].get());
1597 Mock::VerifyAndClearExpectations(mock_devices_[0]);
mukesh agrawal32399322011-09-01 10:53:43 -07001598 }
1599
1600 {
1601 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001602 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001603 EXPECT_EQ(Error::kInvalidArguments, error.type());
1604 }
1605}
1606
Darin Petkovb65c2452012-02-23 15:17:06 +01001607TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001608 KeyValueStore args;
1609 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001610 manager()->GetService(args, &e);
1611 EXPECT_EQ(Error::kInvalidArguments, e.type());
1612 EXPECT_EQ("must specify service type", e.message());
1613}
1614
1615TEST_F(ManagerTest, GetServiceUnknownType) {
1616 KeyValueStore args;
1617 Error e;
Ben Chan923a5022013-09-20 11:23:23 -07001618 args.SetString(kTypeProperty, kTypeEthernet);
Darin Petkovb65c2452012-02-23 15:17:06 +01001619 manager()->GetService(args, &e);
1620 EXPECT_EQ(Error::kNotSupported, e.type());
1621 EXPECT_EQ("service type is unsupported", e.message());
1622}
1623
Paul Stewart35eff132013-04-12 12:08:40 -07001624TEST_F(ManagerTest, GetServiceEthernetEap) {
1625 KeyValueStore args;
1626 Error e;
Paul Stewart55fc64c2013-07-18 09:51:35 -07001627 ServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1628 dispatcher(),
1629 metrics(),
1630 manager());
Ben Chan923a5022013-09-20 11:23:23 -07001631 args.SetString(kTypeProperty, kTypeEthernetEap);
Paul Stewart35eff132013-04-12 12:08:40 -07001632 SetEapProviderService(service);
1633 EXPECT_EQ(service, manager()->GetService(args, &e));
1634 EXPECT_TRUE(e.IsSuccess());
1635}
1636
Darin Petkovb65c2452012-02-23 15:17:06 +01001637TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001638 KeyValueStore args;
1639 Error e;
1640 WiFiServiceRefPtr wifi_service;
Ben Chan923a5022013-09-20 11:23:23 -07001641 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001642 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001643 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001644 manager()->GetService(args, &e);
1645 EXPECT_TRUE(e.IsSuccess());
1646}
1647
Darin Petkov33af05c2012-02-28 10:10:30 +01001648TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1649 KeyValueStore args;
1650 Error e;
Ben Chan923a5022013-09-20 11:23:23 -07001651 args.SetString(kTypeProperty, kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001652 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001653 new StrictMock<MockProfile>(
1654 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001655 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001656 ServiceRefPtr service = manager()->GetService(args, &e);
1657 EXPECT_EQ(Error::kNotSupported, e.type());
1658 EXPECT_FALSE(service);
1659}
1660
Darin Petkovb65c2452012-02-23 15:17:06 +01001661TEST_F(ManagerTest, GetServiceVPN) {
1662 KeyValueStore args;
1663 Error e;
Ben Chan923a5022013-09-20 11:23:23 -07001664 args.SetString(kTypeProperty, kTypeVPN);
1665 args.SetString(kProviderTypeProperty, kProviderOpenVpn);
1666 args.SetString(kProviderHostProperty, "10.8.0.1");
1667 args.SetString(kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001668 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001669 new StrictMock<MockProfile>(
1670 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001671 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001672
1673#if defined(DISABLE_VPN)
1674
1675 ServiceRefPtr service = manager()->GetService(args, &e);
1676 EXPECT_EQ(Error::kNotSupported, e.type());
1677 EXPECT_FALSE(service);
1678
1679#else
1680
Paul Stewart7f5ad572012-06-04 15:18:54 -07001681 ServiceRefPtr updated_service;
1682 EXPECT_CALL(*profile, UpdateService(_))
1683 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1684 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001685 EXPECT_CALL(*profile, LoadService(_))
1686 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001687 EXPECT_CALL(*profile, ConfigureService(_))
1688 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001689 ServiceRefPtr service = manager()->GetService(args, &e);
1690 EXPECT_TRUE(e.IsSuccess());
1691 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001692 EXPECT_EQ(service, updated_service);
1693 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001694
1695#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001696}
1697
Ben Chan520eb172013-10-30 20:51:04 -07001698#if !defined(DISABLE_WIMAX)
1699
Darin Petkovc63dcf02012-05-24 11:51:43 +02001700TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1701 KeyValueStore args;
1702 Error e;
Ben Chan923a5022013-09-20 11:23:23 -07001703 args.SetString(kTypeProperty, kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001704 ServiceRefPtr service = manager()->GetService(args, &e);
1705 EXPECT_EQ(Error::kInvalidArguments, e.type());
1706 EXPECT_EQ("Missing WiMAX network id.", e.message());
1707 EXPECT_FALSE(service);
1708}
1709
Darin Petkovd1cd7972012-05-22 15:26:15 +02001710TEST_F(ManagerTest, GetServiceWiMax) {
1711 KeyValueStore args;
1712 Error e;
Ben Chan923a5022013-09-20 11:23:23 -07001713 args.SetString(kTypeProperty, kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001714 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
Ben Chan923a5022013-09-20 11:23:23 -07001715 args.SetString(kNameProperty, "WiMAX Network");
Darin Petkovc63dcf02012-05-24 11:51:43 +02001716 ServiceRefPtr service = manager()->GetService(args, &e);
1717 EXPECT_TRUE(e.IsSuccess());
1718 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001719}
1720
Ben Chan520eb172013-10-30 20:51:04 -07001721#endif // DISABLE_WIMAX
1722
Paul Stewart7f61e522012-03-22 11:13:45 -07001723TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1724 // Manager calls ActiveProfile() so we need at least one profile installed.
1725 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001726 new NiceMock<MockProfile>(
1727 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001728 AdoptProfile(manager(), profile);
1729
1730 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001731 args.SetString(kProfileProperty, "xxx");
Paul Stewart7f61e522012-03-22 11:13:45 -07001732 Error error;
1733 manager()->ConfigureService(args, &error);
1734 EXPECT_EQ(Error::kInvalidArguments, error.type());
1735 EXPECT_EQ("Invalid profile name xxx", error.message());
1736}
1737
1738TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1739 // Manager calls ActiveProfile() so we need at least one profile installed.
1740 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001741 new NiceMock<MockProfile>(
1742 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001743 AdoptProfile(manager(), profile);
1744
1745 KeyValueStore args;
1746 Error error;
1747 manager()->ConfigureService(args, &error);
1748 EXPECT_EQ(Error::kInvalidArguments, error.type());
1749 EXPECT_EQ("must specify service type", error.message());
1750}
1751
1752// A registered service in the ephemeral profile should be moved to the
1753// active profile as a part of configuration if no profile was explicitly
1754// specified.
1755TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1756 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001757 new NiceMock<MockProfile>(
1758 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001759
1760 AdoptProfile(manager(), profile); // This is now the active profile.
1761
Paul Stewartd2e1c362013-03-03 19:06:07 -08001762 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001763 scoped_refptr<MockWiFiService> service(
1764 new NiceMock<MockWiFiService>(control_interface(),
1765 dispatcher(),
1766 metrics(),
1767 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001768 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001769 ssid,
1770 "",
1771 "",
1772 false));
1773
1774 manager()->RegisterService(service);
1775 service->set_profile(GetEphemeralProfile(manager()));
1776
Paul Stewart3c504012013-01-17 17:49:58 -08001777 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001778 .WillOnce(Return(service));
1779 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1780 .WillOnce(Return(true));
1781 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1782 .WillOnce(Return(true));
1783
1784 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001785 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewart7f61e522012-03-22 11:13:45 -07001786 Error error;
1787 manager()->ConfigureService(args, &error);
1788 EXPECT_TRUE(error.IsSuccess());
1789}
1790
Paul Stewart2c575d22012-12-07 12:28:57 -08001791// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001792// specify a profile, it should be moved from the profile it was previously
1793// in to the specified profile if one was requested.
1794TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1795 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001796 new NiceMock<MockProfile>(
1797 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001798 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001799 new NiceMock<MockProfile>(
1800 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001801
1802 const string kProfileName0 = "profile0";
1803 const string kProfileName1 = "profile1";
1804
1805 EXPECT_CALL(*profile0, GetRpcIdentifier())
1806 .WillRepeatedly(Return(kProfileName0));
1807 EXPECT_CALL(*profile1, GetRpcIdentifier())
1808 .WillRepeatedly(Return(kProfileName1));
1809
1810 AdoptProfile(manager(), profile0);
1811 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1812
Paul Stewartd2e1c362013-03-03 19:06:07 -08001813 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001814 scoped_refptr<MockWiFiService> service(
1815 new NiceMock<MockWiFiService>(control_interface(),
1816 dispatcher(),
1817 metrics(),
1818 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001819 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001820 ssid,
1821 "",
1822 "",
1823 false));
1824
1825 manager()->RegisterService(service);
1826 service->set_profile(profile1);
1827
Paul Stewart3c504012013-01-17 17:49:58 -08001828 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001829 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001830 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1831 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001832 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1833 .WillOnce(Return(true));
1834 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1835 .WillOnce(Return(true));
1836 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1837 .WillOnce(Return(true));
1838
1839 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001840 args.SetString(kTypeProperty, kTypeWifi);
1841 args.SetString(kProfileProperty, kProfileName0);
Paul Stewart7f61e522012-03-22 11:13:45 -07001842 Error error;
1843 manager()->ConfigureService(args, &error);
1844 EXPECT_TRUE(error.IsSuccess());
1845 service->set_profile(NULL); // Breaks refcounting loop.
1846}
1847
Paul Stewart2c575d22012-12-07 12:28:57 -08001848// If we configure a service that is already a member of the specified
1849// profile, the Manager should not call LoadService or AdoptService again
1850// on this service.
1851TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1852 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001853 new NiceMock<MockProfile>(
1854 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001855
1856 const string kProfileName0 = "profile0";
1857
1858 EXPECT_CALL(*profile0, GetRpcIdentifier())
1859 .WillRepeatedly(Return(kProfileName0));
1860
1861 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1862
Paul Stewartd2e1c362013-03-03 19:06:07 -08001863 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001864 scoped_refptr<MockWiFiService> service(
1865 new NiceMock<MockWiFiService>(control_interface(),
1866 dispatcher(),
1867 metrics(),
1868 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001869 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001870 ssid,
1871 "",
1872 "",
1873 false));
1874
1875 manager()->RegisterService(service);
1876 service->set_profile(profile0);
1877
Paul Stewart3c504012013-01-17 17:49:58 -08001878 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001879 .WillOnce(Return(service));
1880 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1881 .Times(0);
1882 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1883 .WillOnce(Return(true));
1884 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1885 .Times(0);
1886
1887 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001888 args.SetString(kTypeProperty, kTypeWifi);
1889 args.SetString(kProfileProperty, kProfileName0);
Paul Stewart2c575d22012-12-07 12:28:57 -08001890 Error error;
1891 manager()->ConfigureService(args, &error);
1892 EXPECT_TRUE(error.IsSuccess());
1893 service->set_profile(NULL); // Breaks refcounting loop.
1894}
1895
Paul Stewart7f61e522012-03-22 11:13:45 -07001896// An unregistered service should remain unregistered, but its contents should
1897// be saved to the specified profile nonetheless.
1898TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1899 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001900 new NiceMock<MockProfile>(
1901 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001902 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001903 new NiceMock<MockProfile>(
1904 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001905
1906 const string kProfileName0 = "profile0";
1907 const string kProfileName1 = "profile1";
1908
1909 EXPECT_CALL(*profile0, GetRpcIdentifier())
1910 .WillRepeatedly(Return(kProfileName0));
1911 EXPECT_CALL(*profile1, GetRpcIdentifier())
1912 .WillRepeatedly(Return(kProfileName1));
1913
1914 AdoptProfile(manager(), profile0);
1915 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1916
Paul Stewartd2e1c362013-03-03 19:06:07 -08001917 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001918 scoped_refptr<MockWiFiService> service(
1919 new NiceMock<MockWiFiService>(control_interface(),
1920 dispatcher(),
1921 metrics(),
1922 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001923 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001924 ssid,
1925 "",
1926 "",
1927 false));
1928
1929 service->set_profile(profile1);
1930
Paul Stewart3c504012013-01-17 17:49:58 -08001931 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001932 .WillOnce(Return(service));
1933 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1934 .WillOnce(Return(true));
1935 EXPECT_CALL(*profile0, AdoptService(_))
1936 .Times(0);
1937 EXPECT_CALL(*profile1, AdoptService(_))
1938 .Times(0);
1939
1940 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001941 args.SetString(kTypeProperty, kTypeWifi);
1942 args.SetString(kProfileProperty, kProfileName0);
Paul Stewart7f61e522012-03-22 11:13:45 -07001943 Error error;
1944 manager()->ConfigureService(args, &error);
1945 EXPECT_TRUE(error.IsSuccess());
1946}
1947
Paul Stewartd2e1c362013-03-03 19:06:07 -08001948TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1949 KeyValueStore args;
1950 Error error;
1951 ServiceRefPtr service =
1952 manager()->ConfigureServiceForProfile("", args, &error);
Paul Stewart6ae05892013-07-29 12:21:12 -07001953 EXPECT_EQ(Error::kInvalidArguments, error.type());
1954 EXPECT_EQ("must specify service type", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001955 EXPECT_EQ(NULL, service.get());
1956}
1957
1958TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1959 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001960 args.SetString(kTypeProperty, kTypeCellular);
Paul Stewartd2e1c362013-03-03 19:06:07 -08001961 Error error;
1962 ServiceRefPtr service =
1963 manager()->ConfigureServiceForProfile("", args, &error);
1964 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07001965 EXPECT_EQ("service type is unsupported", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001966 EXPECT_EQ(NULL, service.get());
1967}
1968
1969TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1970 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001971 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08001972 Error error;
1973 ServiceRefPtr service =
1974 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1975 EXPECT_EQ(Error::kNotFound, error.type());
1976 EXPECT_EQ("Profile specified was not found", error.message());
1977 EXPECT_EQ(NULL, service.get());
1978}
1979
1980TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1981 const string kProfileName0 = "profile0";
1982 const string kProfileName1 = "profile1";
1983 scoped_refptr<MockProfile> profile0(
1984 AddNamedMockProfileToManager(manager(), kProfileName0));
1985
1986 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001987 args.SetString(kTypeProperty, kTypeWifi);
1988 args.SetString(kProfileProperty, kProfileName1);
Paul Stewartd2e1c362013-03-03 19:06:07 -08001989 Error error;
1990 ServiceRefPtr service =
1991 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1992 EXPECT_EQ(Error::kInvalidArguments, error.type());
1993 EXPECT_EQ("Profile argument does not match that in "
1994 "the configuration arguments", error.message());
1995 EXPECT_EQ(NULL, service.get());
1996}
1997
1998TEST_F(ManagerTest,
1999 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
2000 const string kProfileName0 = "profile0";
2001 scoped_refptr<MockProfile> profile0(
2002 AddNamedMockProfileToManager(manager(), kProfileName0));
2003 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002004 args.SetString(kTypeProperty, kTypeWifi);
2005 args.SetString(kProfileProperty, kProfileName0);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002006
2007 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2008 .WillOnce(Return(WiFiServiceRefPtr()));
2009 EXPECT_CALL(*wifi_provider_, GetService(_, _))
2010 .WillOnce(Return(WiFiServiceRefPtr()));
2011 Error error;
2012 ServiceRefPtr service =
2013 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2014 // Since we didn't set the error in the GetService expectation above...
2015 EXPECT_TRUE(error.IsSuccess());
2016 EXPECT_EQ(NULL, service.get());
2017}
2018
2019TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
2020 const string kProfileName0 = "profile0";
2021 scoped_refptr<MockProfile> profile0(
2022 AddNamedMockProfileToManager(manager(), kProfileName0));
2023
2024 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002025 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002026
2027 scoped_refptr<MockWiFiService> mock_service(
2028 new NiceMock<MockWiFiService>(control_interface(),
2029 dispatcher(),
2030 metrics(),
2031 manager(),
2032 wifi_provider_,
2033 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002034 kModeManaged,
2035 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002036 false));
2037 ServiceRefPtr mock_service_generic(mock_service.get());
2038 mock_service->set_profile(profile0);
2039 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2040 .WillOnce(Return(WiFiServiceRefPtr()));
2041 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
2042 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
2043 .WillOnce(Return(true));
2044 Error error;
2045 ServiceRefPtr service =
2046 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2047 EXPECT_TRUE(error.IsSuccess());
2048 EXPECT_EQ(mock_service.get(), service.get());
2049 mock_service->set_profile(NULL); // Breaks reference cycle.
2050}
2051
2052TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
2053 scoped_refptr<MockService> mock_service(
2054 new NiceMock<MockService>(control_interface(),
2055 dispatcher(),
2056 metrics(),
2057 manager()));
2058 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002059 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002060 manager()->RegisterService(mock_service);
2061 ServiceRefPtr mock_service_generic(mock_service.get());
2062
2063 const string kProfileName = "profile";
2064 scoped_refptr<MockProfile> profile(
2065 AddNamedMockProfileToManager(manager(), kProfileName));
2066 mock_service->set_profile(profile);
2067
2068 EXPECT_CALL(*mock_service, technology())
2069 .WillOnce(Return(Technology::kCellular))
2070 .WillOnce(Return(Technology::kWifi));
2071
2072 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
2073 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2074 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2075
2076 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002077 args.SetString(kTypeProperty, kTypeWifi);
2078 args.SetString(kGuidProperty, kGUID);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002079
2080 // The first attempt should fail because the service reports a technology
2081 // other than "WiFi".
2082 {
2083 Error error;
2084 ServiceRefPtr service =
2085 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2086 EXPECT_EQ(NULL, service.get());
2087 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07002088 EXPECT_EQ("This GUID matches a non-wifi service", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08002089 }
2090
2091 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2092 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2093
2094 {
2095 Error error;
2096 ServiceRefPtr service =
2097 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2098 EXPECT_TRUE(error.IsSuccess());
2099 EXPECT_EQ(mock_service.get(), service.get());
2100 EXPECT_EQ(profile.get(), service->profile().get());
2101 }
2102 mock_service->set_profile(NULL); // Breaks reference cycle.
2103}
2104
2105TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
2106 const string kProfileName = "profile";
2107 scoped_refptr<MockProfile> profile(
2108 AddNamedMockProfileToManager(manager(), kProfileName));
2109
2110 scoped_refptr<MockWiFiService> mock_service(
2111 new NiceMock<MockWiFiService>(control_interface(),
2112 dispatcher(),
2113 metrics(),
2114 manager(),
2115 wifi_provider_,
2116 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002117 kModeManaged,
2118 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002119 false));
2120 mock_service->set_profile(profile);
2121 ServiceRefPtr mock_service_generic(mock_service.get());
2122
2123 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002124 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002125 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2126 .WillOnce(Return(mock_service));
2127 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2128 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2129 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2130 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2131
2132 Error error;
2133 ServiceRefPtr service =
2134 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2135 EXPECT_TRUE(error.IsSuccess());
2136 EXPECT_EQ(mock_service.get(), service.get());
2137 EXPECT_EQ(profile.get(), service->profile().get());
2138 mock_service->set_profile(NULL); // Breaks reference cycle.
2139}
2140
2141TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2142 const string kProfileName = "profile";
2143 scoped_refptr<MockProfile> profile(
2144 AddNamedMockProfileToManager(manager(), kProfileName));
2145
2146 scoped_refptr<MockWiFiService> mock_service(
2147 new NiceMock<MockWiFiService>(control_interface(),
2148 dispatcher(),
2149 metrics(),
2150 manager(),
2151 wifi_provider_,
2152 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002153 kModeManaged,
2154 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002155 false));
2156 mock_service->set_profile(GetEphemeralProfile(manager()));
2157 ServiceRefPtr mock_service_generic(mock_service.get());
2158
2159 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002160 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002161 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2162 .WillOnce(Return(mock_service));
2163 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2164 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2165 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2166
2167 Error error;
2168 ServiceRefPtr service =
2169 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2170 EXPECT_TRUE(error.IsSuccess());
2171 EXPECT_EQ(mock_service.get(), service.get());
2172 EXPECT_EQ(profile.get(), service->profile().get());
2173 mock_service->set_profile(NULL); // Breaks reference cycle.
2174}
2175
2176TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2177 const string kProfileName0 = "profile0";
2178 scoped_refptr<MockProfile> profile0(
2179 AddNamedMockProfileToManager(manager(), kProfileName0));
2180 const string kProfileName1 = "profile1";
2181 scoped_refptr<MockProfile> profile1(
2182 AddNamedMockProfileToManager(manager(), kProfileName1));
2183
2184 scoped_refptr<MockWiFiService> mock_service(
2185 new NiceMock<MockWiFiService>(control_interface(),
2186 dispatcher(),
2187 metrics(),
2188 manager(),
2189 wifi_provider_,
2190 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002191 kModeManaged,
2192 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002193 false));
2194 manager()->RegisterService(mock_service);
2195 mock_service->set_profile(profile0);
2196 ServiceRefPtr mock_service_generic(mock_service.get());
2197
2198 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002199 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002200 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2201 .WillOnce(Return(mock_service));
2202 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2203 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2204 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2205 // This happens once to make the service loadable for the ConfigureService
2206 // below, and a second time after the service is modified.
2207 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2208 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2209 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2210 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2211
2212 Error error;
2213 ServiceRefPtr service =
2214 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2215 EXPECT_TRUE(error.IsSuccess());
2216 EXPECT_EQ(mock_service.get(), service.get());
2217 mock_service->set_profile(NULL); // Breaks reference cycle.
2218}
2219
2220TEST_F(ManagerTest,
2221 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2222 const string kProfileName0 = "profile0";
2223 scoped_refptr<MockProfile> profile0(
2224 AddNamedMockProfileToManager(manager(), kProfileName0));
2225 const string kProfileName1 = "profile1";
2226 scoped_refptr<MockProfile> profile1(
2227 AddNamedMockProfileToManager(manager(), kProfileName1));
2228
2229 scoped_refptr<MockWiFiService> matching_service(
2230 new StrictMock<MockWiFiService>(control_interface(),
2231 dispatcher(),
2232 metrics(),
2233 manager(),
2234 wifi_provider_,
2235 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002236 kModeManaged,
2237 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002238 false));
2239 matching_service->set_profile(profile1);
2240
2241 // We need to get rid of our reference to this mock service as soon
2242 // as Manager::ConfigureServiceForProfile() takes a reference in its
2243 // call to WiFiProvider::CreateTemporaryService(). This way the
2244 // latter function can keep a DCHECK(service->HasOneRef() even in
2245 // unit tests.
2246 temp_mock_service_ =
2247 new NiceMock<MockWiFiService>(control_interface(),
2248 dispatcher(),
2249 metrics(),
2250 manager(),
2251 wifi_provider_,
2252 vector<uint8_t>(),
Ben Chan923a5022013-09-20 11:23:23 -07002253 kModeManaged,
2254 kSecurityNone,
Paul Stewartd2e1c362013-03-03 19:06:07 -08002255 false);
2256
2257 // Only hold a pointer here so we don't affect the refcount.
2258 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2259
2260 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07002261 args.SetString(kTypeProperty, kTypeWifi);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002262 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2263 .WillOnce(Return(matching_service));
2264 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2265 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2266 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2267 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2268 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2269 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2270 .Times(1);
2271 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2272 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2273
2274 Error error;
2275 ServiceRefPtr service =
2276 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2277 EXPECT_TRUE(error.IsSuccess());
2278 EXPECT_EQ(NULL, service.get());
2279 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2280}
2281
Paul Stewart7a20aa42013-01-17 12:21:41 -08002282TEST_F(ManagerTest, FindMatchingService) {
2283 KeyValueStore args;
2284 {
2285 Error error;
2286 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2287 EXPECT_EQ(Error::kNotFound, error.type());
2288 }
2289
2290 scoped_refptr<MockService> mock_service0(
2291 new NiceMock<MockService>(control_interface(),
2292 dispatcher(),
2293 metrics(),
2294 manager()));
2295 scoped_refptr<MockService> mock_service1(
2296 new NiceMock<MockService>(control_interface(),
2297 dispatcher(),
2298 metrics(),
2299 manager()));
2300 manager()->RegisterService(mock_service0);
2301 manager()->RegisterService(mock_service1);
2302 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2303 .WillOnce(Return(true))
2304 .WillRepeatedly(Return(false));
2305 {
2306 Error error;
2307 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2308 EXPECT_TRUE(error.IsSuccess());
2309 }
2310 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2311 .WillOnce(Return(true))
2312 .WillRepeatedly(Return(false));
2313 {
2314 Error error;
2315 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2316 EXPECT_TRUE(error.IsSuccess());
2317 }
2318 {
2319 Error error;
2320 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2321 EXPECT_EQ(Error::kNotFound, error.type());
2322 }
2323}
2324
Paul Stewart22aa71b2011-09-16 12:15:11 -07002325TEST_F(ManagerTest, TechnologyOrder) {
2326 Error error;
Ben Chan923a5022013-09-20 11:23:23 -07002327 manager()->SetTechnologyOrder(string(kTypeEthernet) + "," + string(kTypeWifi),
2328 &error);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002329 ASSERT_TRUE(error.IsSuccess());
2330 EXPECT_EQ(manager()->GetTechnologyOrder(),
Ben Chan923a5022013-09-20 11:23:23 -07002331 string(kTypeEthernet) + "," + string(kTypeWifi));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002332
Ben Chan923a5022013-09-20 11:23:23 -07002333 manager()->SetTechnologyOrder(string(kTypeEthernet) + "x," +
2334 string(kTypeWifi), &error);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002335 ASSERT_FALSE(error.IsSuccess());
2336 EXPECT_EQ(Error::kInvalidArguments, error.type());
Ben Chan923a5022013-09-20 11:23:23 -07002337 EXPECT_EQ(string(kTypeEthernet) + "," + string(kTypeWifi),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002338 manager()->GetTechnologyOrder());
2339}
2340
2341TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002342 // TODO(quiche): Some of these tests would probably fit better in
2343 // service_unittest, since the actual comparison of Services is
Paul Stewartee6b3d72013-07-12 16:07:51 -07002344 // implemented in Service. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002345
mukesh agrawale37ad322013-10-08 16:33:56 -07002346 // Construct our Services so that the string comparison of
2347 // unique_name_ differs from the numerical comparison of
2348 // serial_number_.
2349 vector<scoped_refptr<MockService>> mock_services;
2350 for (size_t i = 0; i < 11; ++i) {
2351 mock_services.push_back(
2352 new NiceMock<MockService>(control_interface(),
2353 dispatcher(),
2354 metrics(),
2355 manager()));
2356 }
2357 scoped_refptr<MockService> mock_service2 = mock_services[2];
2358 scoped_refptr<MockService> mock_service10 = mock_services[10];
2359 mock_services.clear();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002360
mukesh agrawale37ad322013-10-08 16:33:56 -07002361 manager()->RegisterService(mock_service2);
2362 manager()->RegisterService(mock_service10);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002363
mukesh agrawale37ad322013-10-08 16:33:56 -07002364 // Services should already be sorted by |serial_number_|.
2365 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002366
2367 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002368 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002369 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002370
2371 // Two otherwise equal services should be reordered by strength
mukesh agrawale37ad322013-10-08 16:33:56 -07002372 mock_service10->SetStrength(1);
2373 manager()->UpdateService(mock_service10);
2374 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002375
2376 // Security
mukesh agrawale37ad322013-10-08 16:33:56 -07002377 mock_service2->SetSecurity(Service::kCryptoAes, true, true);
2378 manager()->UpdateService(mock_service2);
2379 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002380
2381 // Technology
mukesh agrawale37ad322013-10-08 16:33:56 -07002382 EXPECT_CALL(*mock_service2.get(), technology())
Joshua Kroll053fa822012-06-05 09:50:43 -07002383 .WillRepeatedly(Return((Technology::kWifi)));
mukesh agrawale37ad322013-10-08 16:33:56 -07002384 EXPECT_CALL(*mock_service10.get(), technology())
Joshua Kroll053fa822012-06-05 09:50:43 -07002385 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002386
2387 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002388 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002389 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002390 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002391
Ben Chan923a5022013-09-20 11:23:23 -07002392 manager()->SetTechnologyOrder(string(kTypeWifi) + "," + string(kTypeEthernet),
2393 &error);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002394 EXPECT_TRUE(error.IsSuccess());
mukesh agrawale37ad322013-10-08 16:33:56 -07002395 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002396
Gaurav Shah435de2c2011-11-17 19:01:07 -08002397 // Priority.
mukesh agrawale37ad322013-10-08 16:33:56 -07002398 mock_service2->SetPriority(1, NULL);
2399 manager()->UpdateService(mock_service2);
2400 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002401
Paul Stewart2da34c02013-10-17 15:28:56 -07002402 // HasEverConnected.
2403 mock_service10->has_ever_connected_ = true;
mukesh agrawale37ad322013-10-08 16:33:56 -07002404 manager()->UpdateService(mock_service10);
2405 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002406
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002407 // Auto-connect.
mukesh agrawale37ad322013-10-08 16:33:56 -07002408 mock_service2->SetAutoConnect(true);
2409 manager()->UpdateService(mock_service2);
2410 mock_service10->SetAutoConnect(false);
2411 manager()->UpdateService(mock_service10);
2412 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002413
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002414 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2415 // to any of the others below, so we reset to the default state after
2416 // testing.
mukesh agrawale37ad322013-10-08 16:33:56 -07002417 EXPECT_CALL(*mock_service10.get(),
2418 IsDependentOn(ServiceRefPtr(mock_service2.get())))
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002419 .WillOnce(Return(true))
2420 .WillRepeatedly(Return(false));
mukesh agrawale37ad322013-10-08 16:33:56 -07002421 manager()->UpdateService(mock_service10);
2422 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
2423 manager()->UpdateService(mock_service2);
2424 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002425
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002426 // Connectable.
mukesh agrawale37ad322013-10-08 16:33:56 -07002427 mock_service10->SetConnectable(true);
2428 manager()->UpdateService(mock_service10);
2429 mock_service2->SetConnectable(false);
2430 manager()->UpdateService(mock_service2);
2431 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002432
2433 // IsFailed.
mukesh agrawale37ad322013-10-08 16:33:56 -07002434 EXPECT_CALL(*mock_service2.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002435 .WillRepeatedly(Return(Service::kStateIdle));
mukesh agrawale37ad322013-10-08 16:33:56 -07002436 EXPECT_CALL(*mock_service2.get(), IsFailed())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002437 .WillRepeatedly(Return(false));
mukesh agrawale37ad322013-10-08 16:33:56 -07002438 manager()->UpdateService(mock_service2);
2439 EXPECT_CALL(*mock_service10.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002440 .WillRepeatedly(Return(Service::kStateFailure));
mukesh agrawale37ad322013-10-08 16:33:56 -07002441 EXPECT_CALL(*mock_service10.get(), IsFailed())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002442 .WillRepeatedly(Return(true));
mukesh agrawale37ad322013-10-08 16:33:56 -07002443 manager()->UpdateService(mock_service10);
2444 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002445
2446 // Connecting.
mukesh agrawale37ad322013-10-08 16:33:56 -07002447 EXPECT_CALL(*mock_service10.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002448 .WillRepeatedly(Return(Service::kStateAssociating));
mukesh agrawale37ad322013-10-08 16:33:56 -07002449 EXPECT_CALL(*mock_service10.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002450 .WillRepeatedly(Return(true));
mukesh agrawale37ad322013-10-08 16:33:56 -07002451 manager()->UpdateService(mock_service10);
2452 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002453
mukesh agrawale37ad322013-10-08 16:33:56 -07002454 // Connected-but-portalled preferred over unconnected.
2455 EXPECT_CALL(*mock_service2.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002456 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawale37ad322013-10-08 16:33:56 -07002457 EXPECT_CALL(*mock_service2.get(), IsConnected())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002458 .WillRepeatedly(Return(true));
mukesh agrawale37ad322013-10-08 16:33:56 -07002459 manager()->UpdateService(mock_service2);
2460 EXPECT_TRUE(ServiceOrderIs(mock_service2, mock_service10));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002461
mukesh agrawale37ad322013-10-08 16:33:56 -07002462 // Connected preferred over connected-but-portalled.
2463 EXPECT_CALL(*mock_service10.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002464 .WillRepeatedly(Return(Service::kStateConnected));
mukesh agrawale37ad322013-10-08 16:33:56 -07002465 EXPECT_CALL(*mock_service10.get(), IsConnected())
Paul Stewarta121c442012-06-09 14:12:58 -07002466 .WillRepeatedly(Return(true));
mukesh agrawale37ad322013-10-08 16:33:56 -07002467 manager()->UpdateService(mock_service10);
2468 EXPECT_TRUE(ServiceOrderIs(mock_service10, mock_service2));
Paul Stewarta121c442012-06-09 14:12:58 -07002469
mukesh agrawale37ad322013-10-08 16:33:56 -07002470 manager()->DeregisterService(mock_service2);
2471 manager()->DeregisterService(mock_service10);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002472}
2473
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002474TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002475 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002476 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002477
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002478 scoped_refptr<MockService> mock_service0(
2479 new NiceMock<MockService>(control_interface(),
2480 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002481 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002482 manager()));
2483 scoped_refptr<MockService> mock_service1(
2484 new NiceMock<MockService>(control_interface(),
2485 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002486 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002487 manager()));
2488
2489 scoped_refptr<MockConnection> mock_connection0(
2490 new NiceMock<MockConnection>(device_info_.get()));
2491 scoped_refptr<MockConnection> mock_connection1(
2492 new NiceMock<MockConnection>(device_info_.get()));
2493
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002494 // A single registered Service, without a connection. The
2495 // DefaultService should be NULL. If a change notification is
2496 // generated, it should reference kNullPath.
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002497 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002498 EXPECT_CALL(*manager_adaptor_,
2499 EmitRpcIdentifierChanged(kDefaultServiceProperty,
2500 DBusAdaptor::kNullPath))
2501 .Times(AnyNumber());
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002502 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002503 CompleteServiceSort();
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002504
2505 // Adding another Service, also without a connection, does not
2506 // change DefaultService. Furthermore, we do not send a change
2507 // notification for DefaultService.
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002508 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002509 EXPECT_CALL(*manager_adaptor_,
2510 EmitRpcIdentifierChanged(kDefaultServiceProperty, _))
2511 .Times(0);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002512 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002513 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002514
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002515 // An explicit sort doesn't change anything, and does not emit a
2516 // change notification for DefaultService.
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002517 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002518 EXPECT_CALL(*manager_adaptor_,
2519 EmitRpcIdentifierChanged(kDefaultServiceProperty, _))
2520 .Times(0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002521 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002522 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002523
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002524 // Re-ordering the unconnected Services doesn't change
2525 // DefaultService, and (hence) does not emit a change notification
2526 // for DefaultService.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002527 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002528 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002529 EXPECT_CALL(*manager_adaptor_,
2530 EmitRpcIdentifierChanged(kDefaultServiceProperty, _))
2531 .Times(0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002532 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002533 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002534
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002535 // Re-ordering the unconnected Services doesn't change
2536 // DefaultService, and (hence) does not emit a change notification
2537 // for DefaultService.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002538 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002539 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002540 EXPECT_CALL(*manager_adaptor_,
2541 EmitRpcIdentifierChanged(kDefaultServiceProperty, _))
2542 .Times(0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002543 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002544 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002545
Paul Stewartce4ec192012-03-14 12:53:46 -07002546 mock_service0->set_mock_connection(mock_connection0);
2547 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002548
mukesh agrawale37ad322013-10-08 16:33:56 -07002549 // If both Services have Connections, the DefaultService follows
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002550 // from ServiceOrderIs. We notify others of the change in
2551 // DefaultService.
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002552 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002553 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002554 EXPECT_CALL(*manager_adaptor_,
2555 EmitRpcIdentifierChanged(kDefaultServiceProperty, _));
Paul Stewartdfa46052012-06-26 09:44:14 -07002556 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002557 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002558
Darin Petkova5e07ef2012-07-09 14:27:57 +02002559 ServiceWatcher service_watcher;
2560 int tag =
2561 manager()->RegisterDefaultServiceCallback(
2562 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2563 service_watcher.AsWeakPtr()));
2564 EXPECT_EQ(1, tag);
2565
mukesh agrawale37ad322013-10-08 16:33:56 -07002566 // Changing the ordering causes the DefaultService to change, and
2567 // appropriate notifications are sent.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002568 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002569 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2570 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002571 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002572 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002573 EXPECT_CALL(*manager_adaptor_,
2574 EmitRpcIdentifierChanged(kDefaultServiceProperty, _));
Paul Stewartdfa46052012-06-26 09:44:14 -07002575 manager()->SortServicesTask();
mukesh agrawale37ad322013-10-08 16:33:56 -07002576 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002577
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002578 // Deregistering a DefaultServiceCallback works as expected. (Later
2579 // code causes DefaultService changes, but we see no further calls
2580 // to |service_watcher|.)
Darin Petkova5e07ef2012-07-09 14:27:57 +02002581 manager()->DeregisterDefaultServiceCallback(tag);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002582 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002583
2584 // Deregistering the current DefaultService causes the other Service
2585 // to become default. Appropriate notifications are sent.
2586 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002587 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002588 EXPECT_CALL(*manager_adaptor_,
2589 EmitRpcIdentifierChanged(kDefaultServiceProperty, _));
mukesh agrawale37ad322013-10-08 16:33:56 -07002590 mock_service1->set_mock_connection(NULL); // So DeregisterService works.
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002591 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002592 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002593
mukesh agrawale37ad322013-10-08 16:33:56 -07002594 // Deregistering the only Service causes the DefaultService to become
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002595 // NULL. Appropriate notifications are sent.
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002596 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002597 EXPECT_CALL(*manager_adaptor_,
2598 EmitRpcIdentifierChanged(kDefaultServiceProperty, _));
mukesh agrawale37ad322013-10-08 16:33:56 -07002599 mock_service0->set_mock_connection(NULL); // So DeregisterService works.
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002600 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002601 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002602
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002603 // An explicit sort doesn't change anything, and does not generate
2604 // an external notification.
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002605 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
mukesh agrawalf2bbad22014-02-25 14:33:32 -08002606 EXPECT_CALL(*manager_adaptor_,
2607 EmitRpcIdentifierChanged(kDefaultServiceProperty, _)).Times(0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002608 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002609}
2610
Darin Petkova5e07ef2012-07-09 14:27:57 +02002611TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2612 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2613 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2614
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002615 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002616 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002617
2618 scoped_refptr<MockService> mock_service(
2619 new NiceMock<MockService>(
2620 control_interface(), dispatcher(), metrics(), manager()));
2621 ServiceRefPtr service = mock_service;
2622 ServiceRefPtr null_service;
2623
2624 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2625 manager()->NotifyDefaultServiceChanged(null_service);
2626
2627 ServiceWatcher service_watcher1;
2628 ServiceWatcher service_watcher2;
2629 int tag1 =
2630 manager()->RegisterDefaultServiceCallback(
2631 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2632 service_watcher1.AsWeakPtr()));
2633 EXPECT_EQ(1, tag1);
2634 int tag2 =
2635 manager()->RegisterDefaultServiceCallback(
2636 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2637 service_watcher2.AsWeakPtr()));
2638 EXPECT_EQ(2, tag2);
2639
2640 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2641 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2642 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2643 manager()->NotifyDefaultServiceChanged(null_service);
2644
2645 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2646 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2647 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2648 manager()->NotifyDefaultServiceChanged(mock_service);
2649
2650 manager()->DeregisterDefaultServiceCallback(tag1);
2651 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2652 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2653 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2654 manager()->NotifyDefaultServiceChanged(mock_service);
2655 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2656
2657 manager()->DeregisterDefaultServiceCallback(tag2);
2658 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2659 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2660 manager()->NotifyDefaultServiceChanged(mock_service);
2661
2662 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2663 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2664}
2665
Peter Qiu9d581932014-04-14 16:37:37 -07002666TEST_F(ManagerTest, ReportServicesOnSameNetwork) {
2667 int connection_id1 = 100;
2668 int connection_id2 = 200;
2669 scoped_refptr<MockService> mock_service1 =
2670 new NiceMock<MockService>(control_interface(), dispatcher(),
2671 metrics(), manager());
2672 mock_service1->set_connection_id(connection_id1);
2673 scoped_refptr<MockService> mock_service2 =
2674 new NiceMock<MockService>(control_interface(), dispatcher(),
2675 metrics(), manager());
2676 mock_service2->set_connection_id(connection_id1);
2677 scoped_refptr<MockService> mock_service3 =
2678 new NiceMock<MockService>(control_interface(), dispatcher(),
2679 metrics(), manager());
2680 mock_service3->set_connection_id(connection_id2);
2681
2682 manager()->RegisterService(mock_service1);
2683 manager()->RegisterService(mock_service2);
2684 manager()->RegisterService(mock_service3);
2685
2686 EXPECT_CALL(*metrics(), NotifyServicesOnSameNetwork(2));
2687 manager()->ReportServicesOnSameNetwork(connection_id1);
2688
2689 EXPECT_CALL(*metrics(), NotifyServicesOnSameNetwork(1));
2690 manager()->ReportServicesOnSameNetwork(connection_id2);
2691}
2692
Gaurav Shah435de2c2011-11-17 19:01:07 -08002693TEST_F(ManagerTest, AvailableTechnologies) {
2694 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2695 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002696 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002697 manager(),
2698 "null4",
2699 "addr4",
2700 0));
2701 manager()->RegisterDevice(mock_devices_[0]);
2702 manager()->RegisterDevice(mock_devices_[1]);
2703 manager()->RegisterDevice(mock_devices_[2]);
2704 manager()->RegisterDevice(mock_devices_[3]);
2705
2706 ON_CALL(*mock_devices_[0].get(), technology())
2707 .WillByDefault(Return(Technology::kEthernet));
2708 ON_CALL(*mock_devices_[1].get(), technology())
2709 .WillByDefault(Return(Technology::kWifi));
2710 ON_CALL(*mock_devices_[2].get(), technology())
2711 .WillByDefault(Return(Technology::kCellular));
2712 ON_CALL(*mock_devices_[3].get(), technology())
2713 .WillByDefault(Return(Technology::kWifi));
2714
2715 set<string> expected_technologies;
2716 expected_technologies.insert(Technology::NameFromIdentifier(
2717 Technology::kEthernet));
2718 expected_technologies.insert(Technology::NameFromIdentifier(
2719 Technology::kWifi));
2720 expected_technologies.insert(Technology::NameFromIdentifier(
2721 Technology::kCellular));
2722 Error error;
2723 vector<string> technologies = manager()->AvailableTechnologies(&error);
2724
2725 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2726 ContainerEq(expected_technologies));
2727}
2728
2729TEST_F(ManagerTest, ConnectedTechnologies) {
2730 scoped_refptr<MockService> connected_service1(
2731 new NiceMock<MockService>(control_interface(),
2732 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002733 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002734 manager()));
2735 scoped_refptr<MockService> connected_service2(
2736 new NiceMock<MockService>(control_interface(),
2737 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002738 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002739 manager()));
2740 scoped_refptr<MockService> disconnected_service1(
2741 new NiceMock<MockService>(control_interface(),
2742 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002743 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002744 manager()));
2745 scoped_refptr<MockService> disconnected_service2(
2746 new NiceMock<MockService>(control_interface(),
2747 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002748 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002749 manager()));
2750
2751 ON_CALL(*connected_service1.get(), IsConnected())
2752 .WillByDefault(Return(true));
2753 ON_CALL(*connected_service2.get(), IsConnected())
2754 .WillByDefault(Return(true));
2755
2756 manager()->RegisterService(connected_service1);
2757 manager()->RegisterService(connected_service2);
2758 manager()->RegisterService(disconnected_service1);
2759 manager()->RegisterService(disconnected_service2);
2760
2761 manager()->RegisterDevice(mock_devices_[0]);
2762 manager()->RegisterDevice(mock_devices_[1]);
2763 manager()->RegisterDevice(mock_devices_[2]);
2764 manager()->RegisterDevice(mock_devices_[3]);
2765
2766 ON_CALL(*mock_devices_[0].get(), technology())
2767 .WillByDefault(Return(Technology::kEthernet));
2768 ON_CALL(*mock_devices_[1].get(), technology())
2769 .WillByDefault(Return(Technology::kWifi));
2770 ON_CALL(*mock_devices_[2].get(), technology())
2771 .WillByDefault(Return(Technology::kCellular));
2772 ON_CALL(*mock_devices_[3].get(), technology())
2773 .WillByDefault(Return(Technology::kWifi));
2774
2775 mock_devices_[0]->SelectService(connected_service1);
2776 mock_devices_[1]->SelectService(disconnected_service1);
2777 mock_devices_[2]->SelectService(disconnected_service2);
2778 mock_devices_[3]->SelectService(connected_service2);
2779
2780 set<string> expected_technologies;
2781 expected_technologies.insert(Technology::NameFromIdentifier(
2782 Technology::kEthernet));
2783 expected_technologies.insert(Technology::NameFromIdentifier(
2784 Technology::kWifi));
2785 Error error;
2786
2787 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2788 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2789 ContainerEq(expected_technologies));
2790}
2791
2792TEST_F(ManagerTest, DefaultTechnology) {
2793 scoped_refptr<MockService> connected_service(
2794 new NiceMock<MockService>(control_interface(),
2795 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002796 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002797 manager()));
2798 scoped_refptr<MockService> disconnected_service(
2799 new NiceMock<MockService>(control_interface(),
2800 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002801 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002802 manager()));
2803
2804 // Connected. WiFi.
2805 ON_CALL(*connected_service.get(), IsConnected())
2806 .WillByDefault(Return(true));
2807 ON_CALL(*connected_service.get(), state())
2808 .WillByDefault(Return(Service::kStateConnected));
2809 ON_CALL(*connected_service.get(), technology())
2810 .WillByDefault(Return(Technology::kWifi));
2811
2812 // Disconnected. Ethernet.
2813 ON_CALL(*disconnected_service.get(), technology())
2814 .WillByDefault(Return(Technology::kEthernet));
2815
2816 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002817 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002818 Error error;
2819 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2820
2821
2822 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002823 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002824 // Connected service should be brought to the front now.
2825 string expected_technology =
2826 Technology::NameFromIdentifier(Technology::kWifi);
2827 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2828}
2829
Paul Stewart212d60f2012-07-12 10:59:13 -07002830TEST_F(ManagerTest, Stop) {
2831 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002832 new NiceMock<MockProfile>(
2833 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002834 AdoptProfile(manager(), profile);
2835 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002836 new NiceMock<MockService>(control_interface(),
2837 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002838 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002839 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002840 manager()->RegisterService(service);
2841 manager()->RegisterDevice(mock_devices_[0]);
2842 EXPECT_CALL(*profile.get(),
2843 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2844 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002845 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002846 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2847 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002848 manager()->Stop();
2849}
2850
mukesh agrawal00917ce2011-11-22 23:56:55 +00002851TEST_F(ManagerTest, UpdateServiceConnected) {
2852 scoped_refptr<MockService> mock_service(
2853 new NiceMock<MockService>(control_interface(),
2854 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002855 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002856 manager()));
2857 manager()->RegisterService(mock_service);
Paul Stewart2da34c02013-10-17 15:28:56 -07002858 EXPECT_FALSE(mock_service->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +00002859 EXPECT_FALSE(mock_service->auto_connect());
2860
Gaurav Shah435de2c2011-11-17 19:01:07 -08002861 EXPECT_CALL(*mock_service.get(), IsConnected())
2862 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002863 manager()->UpdateService(mock_service);
Paul Stewart2da34c02013-10-17 15:28:56 -07002864 // We can't EXPECT_CALL(..., EnableAndRetainAutoConnect), because that
2865 // requires us to mock out EnableAndRetainAutoConnect. And mocking that out
2866 // would break the SortServices test. (crbug.com/206367)
2867 EXPECT_TRUE(mock_service->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +00002868 EXPECT_TRUE(mock_service->auto_connect());
2869}
2870
Paul Stewart2da34c02013-10-17 15:28:56 -07002871TEST_F(ManagerTest, UpdateServiceConnectedPersistAutoConnect) {
Thieu Led4e9e552012-02-16 16:26:07 -08002872 // This tests the case where the user connects to a service that is
2873 // currently associated with a profile. We want to make sure that the
Paul Stewart2da34c02013-10-17 15:28:56 -07002874 // auto_connect flag is set and that the is saved to the current profile.
Thieu Led4e9e552012-02-16 16:26:07 -08002875 scoped_refptr<MockService> mock_service(
2876 new NiceMock<MockService>(control_interface(),
2877 dispatcher(),
2878 metrics(),
2879 manager()));
2880 manager()->RegisterService(mock_service);
Paul Stewart2da34c02013-10-17 15:28:56 -07002881 EXPECT_FALSE(mock_service->retain_auto_connect());
Thieu Led4e9e552012-02-16 16:26:07 -08002882 EXPECT_FALSE(mock_service->auto_connect());
2883
Gary Moraind93615e2012-04-27 11:50:03 -07002884 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002885 new MockProfile(
2886 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002887
Gary Moraind93615e2012-04-27 11:50:03 -07002888 mock_service->set_profile(profile);
2889 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002890 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002891 EXPECT_CALL(*profile,
2892 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002893 manager()->UpdateService(mock_service);
Paul Stewart2da34c02013-10-17 15:28:56 -07002894 // We can't EXPECT_CALL(..., EnableAndRetainAutoConnect), because that
2895 // requires us to mock out EnableAndRetainAutoConnect. And mocking that out
2896 // would break the SortServices test. (crbug.com/206367)
2897 EXPECT_TRUE(mock_service->retain_auto_connect());
Thieu Led4e9e552012-02-16 16:26:07 -08002898 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002899 // This releases the ref on the mock profile.
2900 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002901}
2902
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002903TEST_F(ManagerTest, SaveSuccessfulService) {
2904 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002905 new StrictMock<MockProfile>(
2906 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002907 AdoptProfile(manager(), profile);
2908 scoped_refptr<MockService> service(
2909 new NiceMock<MockService>(control_interface(),
2910 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002911 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002912 manager()));
2913
2914 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2915 ServiceRefPtr expect_service(service.get());
2916
2917 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2918 .WillOnce(Return(false));
2919 manager()->RegisterService(service);
2920
2921 EXPECT_CALL(*service.get(), state())
2922 .WillRepeatedly(Return(Service::kStateConnected));
2923 EXPECT_CALL(*service.get(), IsConnected())
2924 .WillRepeatedly(Return(true));
2925 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2926 .WillOnce(Return(true));
2927 manager()->UpdateService(service);
2928}
2929
Darin Petkove7c6ad32012-06-29 10:22:09 +02002930TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002931 MockProfile *profile0 =
2932 new MockProfile(control_interface(), metrics(), manager(), "");
2933 MockProfile *profile1 =
2934 new MockProfile(control_interface(), metrics(), manager(), "");
2935 MockProfile *profile2 =
2936 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002937 AdoptProfile(manager(), profile0); // Passes ownership.
2938 AdoptProfile(manager(), profile1); // Passes ownership.
2939 AdoptProfile(manager(), profile2); // Passes ownership.
2940 DeviceRefPtr device_ref(mock_devices_[0].get());
2941 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2942 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2943 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2944 manager()->UpdateDevice(mock_devices_[0]);
2945}
2946
Paul Stewart1b253142012-01-26 14:05:52 -08002947TEST_F(ManagerTest, EnumerateProfiles) {
2948 vector<string> profile_paths;
2949 for (size_t i = 0; i < 10; i++) {
2950 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002951 new StrictMock<MockProfile>(
2952 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002953 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002954 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2955 .WillOnce(Return(profile_paths.back()));
2956 AdoptProfile(manager(), profile);
2957 }
2958
2959 Error error;
2960 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2961 EXPECT_TRUE(error.IsSuccess());
2962 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2963 for (size_t i = 0; i < profile_paths.size(); i++) {
2964 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2965 }
2966}
2967
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002968TEST_F(ManagerTest, AutoConnectOnRegister) {
2969 MockServiceRefPtr service = MakeAutoConnectableService();
2970 EXPECT_CALL(*service.get(), AutoConnect());
2971 manager()->RegisterService(service);
2972 dispatcher()->DispatchPendingEvents();
2973}
2974
2975TEST_F(ManagerTest, AutoConnectOnUpdate) {
2976 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002977 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002978 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002979 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002980 manager()->RegisterService(service1);
2981 manager()->RegisterService(service2);
2982 dispatcher()->DispatchPendingEvents();
2983
2984 EXPECT_CALL(*service1.get(), AutoConnect());
2985 EXPECT_CALL(*service2.get(), state())
2986 .WillRepeatedly(Return(Service::kStateFailure));
2987 EXPECT_CALL(*service2.get(), IsFailed())
2988 .WillRepeatedly(Return(true));
2989 EXPECT_CALL(*service2.get(), IsConnected())
2990 .WillRepeatedly(Return(false));
2991 manager()->UpdateService(service2);
2992 dispatcher()->DispatchPendingEvents();
2993}
2994
2995TEST_F(ManagerTest, AutoConnectOnDeregister) {
2996 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002997 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002998 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002999 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00003000 manager()->RegisterService(service1);
3001 manager()->RegisterService(service2);
3002 dispatcher()->DispatchPendingEvents();
3003
3004 EXPECT_CALL(*service1.get(), AutoConnect());
3005 manager()->DeregisterService(service2);
3006 dispatcher()->DispatchPendingEvents();
3007}
3008
Daniel Eratfac09532014-04-17 20:25:59 -07003009TEST_F(ManagerTest, AutoConnectOnSuspending) {
Darin Petkov3ec55342012-09-28 14:04:44 +02003010 MockServiceRefPtr service = MakeAutoConnectableService();
Daniel Eratfac09532014-04-17 20:25:59 -07003011 SetSuspending(true);
Darin Petkov3ec55342012-09-28 14:04:44 +02003012 SetPowerManager();
3013 EXPECT_CALL(*service, AutoConnect()).Times(0);
3014 manager()->RegisterService(service);
3015 dispatcher()->DispatchPendingEvents();
3016}
3017
Daniel Eratfac09532014-04-17 20:25:59 -07003018TEST_F(ManagerTest, AutoConnectOnNotSuspending) {
Darin Petkovca621542012-07-25 14:25:56 +02003019 MockServiceRefPtr service = MakeAutoConnectableService();
Daniel Eratfac09532014-04-17 20:25:59 -07003020 SetSuspending(false);
Darin Petkovca621542012-07-25 14:25:56 +02003021 SetPowerManager();
3022 EXPECT_CALL(*service, AutoConnect());
3023 manager()->RegisterService(service);
3024 dispatcher()->DispatchPendingEvents();
3025}
3026
Paul Stewart63864b62012-11-07 15:10:55 -08003027TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
3028 SetRunning(false);
3029 MockServiceRefPtr service = MakeAutoConnectableService();
3030 EXPECT_CALL(*service, AutoConnect()).Times(0);
3031 manager()->RegisterService(service);
3032 dispatcher()->DispatchPendingEvents();
3033}
3034
Daniel Eratfac09532014-04-17 20:25:59 -07003035TEST_F(ManagerTest, Suspend) {
Darin Petkovca621542012-07-25 14:25:56 +02003036 MockServiceRefPtr service = MakeAutoConnectableService();
Darin Petkovca621542012-07-25 14:25:56 +02003037 SetPowerManager();
3038 EXPECT_CALL(*service, AutoConnect());
3039 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07003040 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02003041 dispatcher()->DispatchPendingEvents();
3042
Daniel Eratfac09532014-04-17 20:25:59 -07003043 const int kSuspendId = 1;
3044 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
3045 OnSuspendImminent(kSuspendId);
3046 EXPECT_CALL(*service, AutoConnect()).Times(0);
Darin Petkovca621542012-07-25 14:25:56 +02003047 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07003048 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02003049
Daniel Eratfac09532014-04-17 20:25:59 -07003050 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
3051 OnSuspendDone(kSuspendId);
3052 EXPECT_CALL(*service, AutoConnect());
Darin Petkovca621542012-07-25 14:25:56 +02003053 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07003054 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02003055}
3056
Darin Petkov3ec55342012-09-28 14:04:44 +02003057TEST_F(ManagerTest, AddTerminationAction) {
Daniel Eratfac09532014-04-17 20:25:59 -07003058 EXPECT_CALL(*power_manager_, AddSuspendDelay(_, _, _, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02003059 SetPowerManager();
3060 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
3061 manager()->AddTerminationAction("action1", base::Closure());
3062 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
3063 manager()->AddTerminationAction("action2", base::Closure());
3064}
3065
3066TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08003067 const char kKey1[] = "action1";
3068 const char kKey2[] = "action2";
Darin Petkov3ec55342012-09-28 14:04:44 +02003069
3070 MockPowerManager &power_manager = *power_manager_;
3071 SetPowerManager();
3072
Ben Chan16d3acb2014-05-13 22:08:14 -07003073 // Removing an action when the hook table is empty.
Daniel Eratfac09532014-04-17 20:25:59 -07003074 EXPECT_CALL(power_manager, RemoveSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02003075 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
3076 manager()->RemoveTerminationAction("unknown");
3077 Mock::VerifyAndClearExpectations(&power_manager);
3078
Daniel Eratfac09532014-04-17 20:25:59 -07003079 EXPECT_CALL(power_manager, AddSuspendDelay(_, _, _, _, _))
3080 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02003081 manager()->AddTerminationAction(kKey1, base::Closure());
3082 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
3083 manager()->AddTerminationAction(kKey2, base::Closure());
Daniel Eratfac09532014-04-17 20:25:59 -07003084 Mock::VerifyAndClearExpectations(&power_manager);
Darin Petkov3ec55342012-09-28 14:04:44 +02003085
Ben Chan16d3acb2014-05-13 22:08:14 -07003086 // Removing an action that ends up with a non-empty hook table.
Daniel Eratfac09532014-04-17 20:25:59 -07003087 EXPECT_CALL(power_manager, RemoveSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02003088 manager()->RemoveTerminationAction(kKey1);
3089 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
3090 Mock::VerifyAndClearExpectations(&power_manager);
3091
Ben Chan16d3acb2014-05-13 22:08:14 -07003092 // Removing the last action.
3093 EXPECT_CALL(power_manager, RemoveSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02003094 manager()->RemoveTerminationAction(kKey2);
3095 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
3096}
3097
3098TEST_F(ManagerTest, RunTerminationActions) {
3099 TerminationActionTest test_action;
3100 const string kActionName = "action";
3101
3102 EXPECT_CALL(test_action, Done(_));
3103 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
3104 test_action.AsWeakPtr()));
3105
3106 manager()->AddTerminationAction(TerminationActionTest::kActionName,
3107 Bind(&TerminationActionTest::Action,
3108 test_action.AsWeakPtr()));
3109 test_action.set_manager(manager());
3110 EXPECT_CALL(test_action, Done(_));
3111 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
3112 test_action.AsWeakPtr()));
3113}
3114
Daniel Erat0818cca2012-12-14 10:16:21 -08003115TEST_F(ManagerTest, OnSuspendImminent) {
3116 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02003117 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Eratfac09532014-04-17 20:25:59 -07003118 EXPECT_CALL(*power_manager_, ReportSuspendReadiness(_, kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003119 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003120 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02003121}
3122
3123TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08003124 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02003125 Error error;
Daniel Eratfac09532014-04-17 20:25:59 -07003126 EXPECT_CALL(*power_manager_, ReportSuspendReadiness(_, kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003127 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003128 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02003129}
3130
Paul Stewartc681fa02012-03-02 19:40:04 -08003131TEST_F(ManagerTest, RecheckPortal) {
3132 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
3133 .WillOnce(Return(false));
3134 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
3135 .WillOnce(Return(true));
3136 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
3137 .Times(0);
3138
3139 manager()->RegisterDevice(mock_devices_[0]);
3140 manager()->RegisterDevice(mock_devices_[1]);
3141 manager()->RegisterDevice(mock_devices_[2]);
3142
3143 manager()->RecheckPortal(NULL);
3144}
3145
Paul Stewartd215af62012-04-24 23:25:50 -07003146TEST_F(ManagerTest, RecheckPortalOnService) {
3147 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
3148 dispatcher(),
3149 metrics(),
3150 manager());
3151 EXPECT_CALL(*mock_devices_[0].get(),
3152 IsConnectedToService(IsRefPtrTo(service)))
3153 .WillOnce(Return(false));
3154 EXPECT_CALL(*mock_devices_[1].get(),
3155 IsConnectedToService(IsRefPtrTo(service)))
3156 .WillOnce(Return(true));
3157 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
3158 .WillOnce(Return(true));
3159 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
3160 .Times(0);
3161
3162 manager()->RegisterDevice(mock_devices_[0]);
3163 manager()->RegisterDevice(mock_devices_[1]);
3164 manager()->RegisterDevice(mock_devices_[2]);
3165
3166 manager()->RecheckPortalOnService(service);
3167}
3168
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003169TEST_F(ManagerTest, GetDefaultService) {
3170 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003171 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003172
3173 scoped_refptr<MockService> mock_service(
3174 new NiceMock<MockService>(control_interface(),
3175 dispatcher(),
3176 metrics(),
3177 manager()));
3178
3179 manager()->RegisterService(mock_service);
3180 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003181 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003182
3183 scoped_refptr<MockConnection> mock_connection(
3184 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07003185 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003186 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003187 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003188
Paul Stewartce4ec192012-03-14 12:53:46 -07003189 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003190 manager()->DeregisterService(mock_service);
3191}
3192
Paul Stewart13ed2252012-03-21 12:52:46 -07003193TEST_F(ManagerTest, GetServiceWithGUID) {
3194 scoped_refptr<MockService> mock_service0(
3195 new NiceMock<MockService>(control_interface(),
3196 dispatcher(),
3197 metrics(),
3198 manager()));
3199
3200 scoped_refptr<MockService> mock_service1(
3201 new NiceMock<MockService>(control_interface(),
3202 dispatcher(),
3203 metrics(),
3204 manager()));
3205
Paul Stewartcb59fed2012-03-21 21:14:46 -07003206 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3207 .Times(0);
3208 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3209 .Times(0);
3210
Paul Stewart13ed2252012-03-21 12:52:46 -07003211 manager()->RegisterService(mock_service0);
3212 manager()->RegisterService(mock_service1);
3213
3214 const string kGUID0 = "GUID0";
3215 const string kGUID1 = "GUID1";
3216
3217 {
3218 Error error;
3219 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3220 EXPECT_FALSE(error.IsSuccess());
3221 EXPECT_FALSE(service);
3222 }
3223
3224 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07003225 args.SetString(kGuidProperty, kGUID1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003226
3227 {
3228 Error error;
3229 ServiceRefPtr service = manager()->GetService(args, &error);
3230 EXPECT_EQ(Error::kInvalidArguments, error.type());
3231 EXPECT_FALSE(service);
3232 }
3233
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003234 mock_service0->SetGuid(kGUID0, NULL);
3235 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003236
3237 {
3238 Error error;
3239 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3240 EXPECT_TRUE(error.IsSuccess());
3241 EXPECT_EQ(mock_service0.get(), service.get());
3242 }
3243
3244 {
3245 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003246 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3247 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003248 ServiceRefPtr service = manager()->GetService(args, &error);
3249 EXPECT_TRUE(error.IsSuccess());
3250 EXPECT_EQ(mock_service1.get(), service.get());
3251 }
3252
3253 manager()->DeregisterService(mock_service0);
3254 manager()->DeregisterService(mock_service1);
3255}
3256
Gary Morain028545d2012-04-07 14:55:52 -07003257
3258TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003259 EXPECT_FALSE(manager()->IsOnline());
3260 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3261
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003262 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003263 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003264 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3265 .Times(AnyNumber());
3266 scoped_refptr<MockService> mock_service0(
3267 new NiceMock<MockService>(control_interface(),
3268 dispatcher(),
3269 metrics(),
3270 manager()));
3271
3272 scoped_refptr<MockService> mock_service1(
3273 new NiceMock<MockService>(control_interface(),
3274 dispatcher(),
3275 metrics(),
3276 manager()));
3277
3278 EXPECT_CALL(*mock_service0.get(), IsConnected())
3279 .WillRepeatedly(Return(false));
3280 EXPECT_CALL(*mock_service1.get(), IsConnected())
3281 .WillRepeatedly(Return(false));
3282
3283 manager()->RegisterService(mock_service0);
3284 manager()->RegisterService(mock_service1);
3285
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003286 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003287 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3288
3289 manager()->DeregisterService(mock_service0);
3290 manager()->DeregisterService(mock_service1);
3291}
3292
3293TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003294 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003295 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003296 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3297 .Times(AnyNumber());
3298 scoped_refptr<MockService> mock_service0(
3299 new NiceMock<MockService>(control_interface(),
3300 dispatcher(),
3301 metrics(),
3302 manager()));
3303
3304 scoped_refptr<MockService> mock_service1(
3305 new NiceMock<MockService>(control_interface(),
3306 dispatcher(),
3307 metrics(),
3308 manager()));
3309
3310 EXPECT_CALL(*mock_service0.get(), IsConnected())
3311 .WillRepeatedly(Return(false));
3312 EXPECT_CALL(*mock_service1.get(), IsConnected())
3313 .WillRepeatedly(Return(true));
3314 EXPECT_CALL(*mock_service0.get(), state())
3315 .WillRepeatedly(Return(Service::kStateIdle));
3316 EXPECT_CALL(*mock_service1.get(), state())
3317 .WillRepeatedly(Return(Service::kStateConnected));
3318
3319 manager()->RegisterService(mock_service0);
3320 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003321 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003322
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003323 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003324 EXPECT_EQ("online", manager()->CalculateState(NULL));
3325
3326 manager()->DeregisterService(mock_service0);
3327 manager()->DeregisterService(mock_service1);
3328}
3329
Paul Stewart03e29f72013-09-26 00:49:48 -07003330TEST_F(ManagerTest, RefreshConnectionState) {
3331 EXPECT_CALL(*manager_adaptor_,
3332 EmitStringChanged(kConnectionStateProperty, kStateIdle));
3333 RefreshConnectionState();
3334 Mock::VerifyAndClearExpectations(manager_adaptor_);
3335
3336 scoped_refptr<MockService> mock_service(
3337 new NiceMock<MockService>(control_interface(),
3338 dispatcher(),
3339 metrics(),
3340 manager()));
3341 EXPECT_CALL(*manager_adaptor_,
3342 EmitStringChanged(kConnectionStateProperty, _)).Times(0);
3343 manager()->RegisterService(mock_service);
3344 RefreshConnectionState();
3345
3346 scoped_refptr<MockConnection> mock_connection(
3347 new NiceMock<MockConnection>(device_info_.get()));
3348 mock_service->set_mock_connection(mock_connection);
3349 EXPECT_CALL(*mock_service, state())
3350 .WillOnce(Return(Service::kStateIdle));
3351 RefreshConnectionState();
3352
3353 Mock::VerifyAndClearExpectations(manager_adaptor_);
3354 EXPECT_CALL(*mock_service, state())
3355 .WillOnce(Return(Service::kStatePortal));
3356 EXPECT_CALL(*manager_adaptor_,
3357 EmitStringChanged(kConnectionStateProperty, kStatePortal));
3358 RefreshConnectionState();
3359 Mock::VerifyAndClearExpectations(manager_adaptor_);
3360
3361 mock_service->set_mock_connection(NULL);
3362 manager()->DeregisterService(mock_service);
3363}
3364
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003365TEST_F(ManagerTest, StartupPortalList) {
3366 // Simulate loading value from the default profile.
3367 const string kProfileValue("wifi,vpn");
3368 manager()->props_.check_portal_list = kProfileValue;
3369
3370 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3371 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3372 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3373
3374 const string kStartupValue("cellular,ethernet");
3375 manager()->SetStartupPortalList(kStartupValue);
3376 // Ensure profile value is not overwritten, so when we save the default
3377 // profile, the correct value will still be written.
3378 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3379
3380 // However we should read back a different list.
3381 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3382 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3383 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3384
3385 const string kRuntimeValue("ppp");
3386 // Setting a runtime value over the control API should overwrite both
3387 // the profile value and what we read back.
3388 Error error;
3389 manager()->mutable_store()->SetStringProperty(
Ben Chan923a5022013-09-20 11:23:23 -07003390 kCheckPortalListProperty,
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003391 kRuntimeValue,
3392 &error);
3393 ASSERT_TRUE(error.IsSuccess());
3394 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3395 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3396 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3397 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3398}
3399
Paul Stewart036dba02012-08-07 12:34:41 -07003400TEST_F(ManagerTest, LinkMonitorEnabled) {
3401 const string kEnabledTechnologies("wifi,vpn");
3402 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3403 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3404 EXPECT_FALSE(
3405 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3406}
3407
Paul Stewart85aea152013-01-22 09:31:56 -08003408TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003409 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003410 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003411 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003412 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003413 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003414 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3415 AdoptProfile(manager(), profile);
3416 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3417 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3418 scoped_ptr<MockStore> store1(new MockStore);
3419 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3420}
3421
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003422TEST_F(ManagerTest, SetEnabledStateForTechnology) {
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003423 Error error(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003424 DisableTechnologyReplyHandler disable_technology_reply_handler;
3425 ResultCallback disable_technology_callback(
3426 Bind(&DisableTechnologyReplyHandler::ReportResult,
3427 disable_technology_reply_handler.AsWeakPtr()));
3428 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_)).Times(0);
3429
Ben Chan923a5022013-09-20 11:23:23 -07003430 manager()->SetEnabledStateForTechnology(kTypeEthernet, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003431 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003432 EXPECT_TRUE(error.IsSuccess());
3433
Joshua Krollda798622012-06-05 12:30:48 -07003434 ON_CALL(*mock_devices_[0], technology())
3435 .WillByDefault(Return(Technology::kEthernet));
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003436 ON_CALL(*mock_devices_[1], technology())
3437 .WillByDefault(Return(Technology::kCellular));
3438 ON_CALL(*mock_devices_[2], technology())
3439 .WillByDefault(Return(Technology::kCellular));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003440
3441 manager()->RegisterDevice(mock_devices_[0]);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003442 manager()->RegisterDevice(mock_devices_[1]);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003443
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003444 // Ethernet Device is disabled, so disable succeeds immediately.
Arman Uguray2f352e62013-08-28 19:12:53 -07003445 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _))
3446 .WillOnce(WithArg<1>(Invoke(SetErrorSuccess)));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003447 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003448 manager()->SetEnabledStateForTechnology(kTypeEthernet, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003449 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003450 EXPECT_TRUE(error.IsSuccess());
3451
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003452 // Ethernet Device is enabled, and mock doesn't change error from
3453 // kOperationInitiated, so expect disable to say operation in progress.
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003454 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3455 mock_devices_[0]->enabled_ = true;
3456 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003457 manager()->SetEnabledStateForTechnology(kTypeEthernet, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003458 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003459 EXPECT_TRUE(error.IsOngoing());
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003460
3461 // Ethernet Device is disabled, and mock doesn't change error from
3462 // kOperationInitiated, so expect enable to say operation in progress.
3463 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3464 mock_devices_[0]->enabled_ = false;
3465 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003466 manager()->SetEnabledStateForTechnology(kTypeEthernet, true,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003467 &error, disable_technology_callback);
3468 EXPECT_TRUE(error.IsOngoing());
3469
3470 // Cellular Device is enabled, but disable failed.
3471 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3472 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3473 mock_devices_[1]->enabled_ = true;
3474 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003475 manager()->SetEnabledStateForTechnology(kTypeCellular, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003476 &error, disable_technology_callback);
3477 EXPECT_EQ(Error::kPermissionDenied, error.type());
3478
3479 // Multiple Cellular Devices in enabled state. Should indicate IsOngoing
3480 // if one is in progress (even if the other completed immediately).
3481 manager()->RegisterDevice(mock_devices_[2]);
3482 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3483 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3484 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _));
3485 mock_devices_[1]->enabled_ = true;
3486 mock_devices_[2]->enabled_ = true;
3487 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003488 manager()->SetEnabledStateForTechnology(kTypeCellular, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003489 &error, disable_technology_callback);
3490 EXPECT_TRUE(error.IsOngoing());
3491
3492 // ...and order doesn't matter.
3493 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _));
3494 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3495 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3496 mock_devices_[1]->enabled_ = true;
3497 mock_devices_[2]->enabled_ = true;
3498 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003499 manager()->SetEnabledStateForTechnology(kTypeCellular, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003500 &error, disable_technology_callback);
3501 EXPECT_TRUE(error.IsOngoing());
3502 Mock::VerifyAndClearExpectations(&disable_technology_reply_handler);
3503
3504 // Multiple Cellular Devices in enabled state. Even if all disable
3505 // operations complete asynchronously, we only get one call to the
3506 // DisableTechnologyReplyHandler::ReportResult.
3507 ResultCallback device1_result_callback;
3508 ResultCallback device2_result_callback;
3509 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3510 .WillOnce(SaveArg<2>(&device1_result_callback));
3511 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3512 .WillOnce(DoAll(WithArg<1>(Invoke(SetErrorPermissionDenied)),
3513 SaveArg<2>(&device2_result_callback)));
3514 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_));
3515 mock_devices_[1]->enabled_ = true;
3516 mock_devices_[2]->enabled_ = true;
3517 error.Populate(Error::kOperationInitiated);
Ben Chan923a5022013-09-20 11:23:23 -07003518 manager()->SetEnabledStateForTechnology(kTypeCellular, false,
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003519 &error, disable_technology_callback);
3520 EXPECT_TRUE(error.IsOngoing());
3521 device1_result_callback.Run(Error(Error::kSuccess));
3522 device2_result_callback.Run(Error(Error::kSuccess));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003523}
3524
Paul Stewart4d5efb72012-09-17 12:24:34 -07003525TEST_F(ManagerTest, IgnoredSearchList) {
3526 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003527 vector<string> ignored_paths;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003528 SetResolver(resolver.get());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003529
3530 const string kIgnored0 = "chromium.org";
3531 ignored_paths.push_back(kIgnored0);
3532 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003533 SetIgnoredDNSSearchPaths(kIgnored0, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003534 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3535
3536 const string kIgnored1 = "google.com";
3537 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3538 ignored_paths.push_back(kIgnored1);
3539 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003540 SetIgnoredDNSSearchPaths(kIgnoredSum, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003541 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3542
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003543 ignored_paths.clear();
3544 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3545 SetIgnoredDNSSearchPaths("", NULL);
3546 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3547
Paul Stewart4d5efb72012-09-17 12:24:34 -07003548 SetResolver(Resolver::GetInstance());
3549}
3550
Paul Stewartbfb82552012-10-24 16:48:48 -07003551TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3552 // Test to make sure that every service state-change causes the
3553 // Manager to emit a new service list.
3554 scoped_refptr<MockService> mock_service(
3555 new NiceMock<MockService>(control_interface(),
3556 dispatcher(),
3557 metrics(),
3558 manager()));
3559 EXPECT_CALL(*mock_service, state())
3560 .WillRepeatedly(Return(Service::kStateIdle));
3561
3562 manager()->RegisterService(mock_service);
3563 EXPECT_CALL(
3564 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Paul Stewart19a14db2014-05-30 11:31:26 -07003565 kServiceCompleteListProperty, _)).Times(1);
3566 EXPECT_CALL(
3567 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Ben Chan923a5022013-09-20 11:23:23 -07003568 kServicesProperty, _)).Times(1);
Paul Stewartbfb82552012-10-24 16:48:48 -07003569 EXPECT_CALL(
3570 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Ben Chan923a5022013-09-20 11:23:23 -07003571 kServiceWatchListProperty, _)).Times(1);
Paul Stewartbfb82552012-10-24 16:48:48 -07003572 CompleteServiceSort();
3573
3574 Mock::VerifyAndClearExpectations(manager_adaptor_);
3575 EXPECT_CALL(
3576 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Paul Stewart19a14db2014-05-30 11:31:26 -07003577 kServiceCompleteListProperty, _)).Times(1);
3578 EXPECT_CALL(
3579 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Ben Chan923a5022013-09-20 11:23:23 -07003580 kServicesProperty, _)).Times(1);
Paul Stewartbfb82552012-10-24 16:48:48 -07003581 EXPECT_CALL(
3582 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
Ben Chan923a5022013-09-20 11:23:23 -07003583 kServiceWatchListProperty, _)).Times(1);
Paul Stewartbfb82552012-10-24 16:48:48 -07003584 manager()->UpdateService(mock_service.get());
3585 CompleteServiceSort();
3586
3587 manager()->DeregisterService(mock_service);
3588}
3589
3590TEST_F(ManagerTest, EnumerateServices) {
3591 scoped_refptr<MockService> mock_service(
3592 new NiceMock<MockService>(control_interface(),
3593 dispatcher(),
3594 metrics(),
3595 manager()));
3596 manager()->RegisterService(mock_service);
3597
3598 EXPECT_CALL(*mock_service, state())
3599 .WillRepeatedly(Return(Service::kStateConnected));
3600 EXPECT_CALL(*mock_service, IsVisible())
3601 .WillRepeatedly(Return(false));
3602 EXPECT_TRUE(EnumerateAvailableServices().empty());
3603 EXPECT_TRUE(EnumerateWatchedServices().empty());
3604
3605 EXPECT_CALL(*mock_service, state())
3606 .WillRepeatedly(Return(Service::kStateIdle));
3607 EXPECT_TRUE(EnumerateAvailableServices().empty());
3608 EXPECT_TRUE(EnumerateWatchedServices().empty());
3609
3610 EXPECT_CALL(*mock_service, IsVisible())
3611 .WillRepeatedly(Return(true));
3612 Service::ConnectState unwatched_states[] = {
3613 Service::kStateUnknown,
3614 Service::kStateIdle,
3615 Service::kStateFailure
3616 };
3617 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3618 EXPECT_CALL(*mock_service, state())
3619 .WillRepeatedly(Return(unwatched_states[i]));
3620 EXPECT_FALSE(EnumerateAvailableServices().empty());
3621 EXPECT_TRUE(EnumerateWatchedServices().empty());
3622 }
3623
3624 Service::ConnectState watched_states[] = {
3625 Service::kStateAssociating,
3626 Service::kStateConfiguring,
3627 Service::kStateConnected,
Paul Stewartbfb82552012-10-24 16:48:48 -07003628 Service::kStatePortal,
3629 Service::kStateOnline
3630 };
3631 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3632 EXPECT_CALL(*mock_service, state())
3633 .WillRepeatedly(Return(watched_states[i]));
3634 EXPECT_FALSE(EnumerateAvailableServices().empty());
3635 EXPECT_FALSE(EnumerateWatchedServices().empty());
3636 }
3637
3638 manager()->DeregisterService(mock_service);
3639}
3640
Paul Stewart39db5ca2013-03-18 14:15:17 -07003641TEST_F(ManagerTest, ConnectToBestServices) {
3642 scoped_refptr<MockService> wifi_service0(
3643 new NiceMock<MockService>(control_interface(),
3644 dispatcher(),
3645 metrics(),
3646 manager()));
3647 EXPECT_CALL(*wifi_service0.get(), state())
3648 .WillRepeatedly(Return(Service::kStateIdle));
3649 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3650 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003651 wifi_service0->SetConnectable(true);
3652 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003653 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3654 EXPECT_CALL(*wifi_service0.get(), technology())
3655 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003656 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3657 .WillRepeatedly(Return(false));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003658 EXPECT_CALL(*wifi_service0.get(), explicitly_disconnected())
3659 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003660
3661 scoped_refptr<MockService> wifi_service1(
3662 new NiceMock<MockService>(control_interface(),
3663 dispatcher(),
3664 metrics(),
3665 manager()));
3666 EXPECT_CALL(*wifi_service1.get(), state())
3667 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003668 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3669 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003670 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3671 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003672 wifi_service1->SetAutoConnect(true);
3673 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003674 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3675 EXPECT_CALL(*wifi_service1.get(), technology())
3676 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003677 EXPECT_CALL(*wifi_service1.get(), explicitly_disconnected())
3678 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003679
3680 scoped_refptr<MockService> wifi_service2(
3681 new NiceMock<MockService>(control_interface(),
3682 dispatcher(),
3683 metrics(),
3684 manager()));
3685 EXPECT_CALL(*wifi_service2.get(), state())
3686 .WillRepeatedly(Return(Service::kStateConnected));
3687 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3688 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003689 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3690 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003691 wifi_service2->SetAutoConnect(true);
3692 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003693 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3694 EXPECT_CALL(*wifi_service2.get(), technology())
3695 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003696 EXPECT_CALL(*wifi_service2.get(), explicitly_disconnected())
3697 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003698
3699 manager()->RegisterService(wifi_service0);
3700 manager()->RegisterService(wifi_service1);
3701 manager()->RegisterService(wifi_service2);
3702
3703 CompleteServiceSort();
3704 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3705
3706 scoped_refptr<MockService> cell_service(
3707 new NiceMock<MockService>(control_interface(),
3708 dispatcher(),
3709 metrics(),
3710 manager()));
3711
3712 EXPECT_CALL(*cell_service.get(), state())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003713 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003714 EXPECT_CALL(*cell_service.get(), IsConnected())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003715 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003716 EXPECT_CALL(*cell_service.get(), IsVisible())
3717 .WillRepeatedly(Return(true));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003718 cell_service->SetAutoConnect(true);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003719 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003720 EXPECT_CALL(*cell_service.get(), technology())
3721 .WillRepeatedly(Return(Technology::kCellular));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003722 EXPECT_CALL(*cell_service.get(), explicitly_disconnected())
3723 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003724 manager()->RegisterService(cell_service);
3725
Arman Uguray6fe4f262013-08-02 20:21:55 -07003726 scoped_refptr<MockService> wimax_service(
3727 new NiceMock<MockService>(control_interface(),
3728 dispatcher(),
3729 metrics(),
3730 manager()));
3731
3732 EXPECT_CALL(*wimax_service.get(), state())
3733 .WillRepeatedly(Return(Service::kStateConnected));
3734 EXPECT_CALL(*wimax_service.get(), IsConnected())
3735 .WillRepeatedly(Return(true));
3736 EXPECT_CALL(*wimax_service.get(), IsVisible())
3737 .WillRepeatedly(Return(true));
3738 wimax_service->SetAutoConnect(true);
3739 wimax_service->SetConnectable(true);
3740 EXPECT_CALL(*wimax_service.get(), technology())
3741 .WillRepeatedly(Return(Technology::kWiMax));
3742 EXPECT_CALL(*wimax_service.get(), explicitly_disconnected())
3743 .WillRepeatedly(Return(false));
3744 manager()->RegisterService(wimax_service);
3745
Paul Stewart39db5ca2013-03-18 14:15:17 -07003746 scoped_refptr<MockService> vpn_service(
3747 new NiceMock<MockService>(control_interface(),
3748 dispatcher(),
3749 metrics(),
3750 manager()));
3751
3752 EXPECT_CALL(*vpn_service.get(), state())
3753 .WillRepeatedly(Return(Service::kStateIdle));
3754 EXPECT_CALL(*vpn_service.get(), IsConnected())
3755 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003756 EXPECT_CALL(*vpn_service.get(), IsVisible())
3757 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003758 wifi_service2->SetAutoConnect(false);
3759 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003760 EXPECT_CALL(*vpn_service.get(), technology())
3761 .WillRepeatedly(Return(Technology::kVPN));
3762 manager()->RegisterService(vpn_service);
3763
3764 // The connected services should be at the top.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003765 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003766
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003767 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3768 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003769 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003770 EXPECT_CALL(*cell_service.get(), Connect(_, _))
3771 .Times(0); // Explicitly disconnected.
3772 EXPECT_CALL(*wimax_service.get(), Connect(_, _)).Times(0); // Is connected.
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003773 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003774
3775 manager()->ConnectToBestServices(NULL);
3776 dispatcher()->DispatchPendingEvents();
3777
3778 // After this operation, since the Connect calls above are mocked and
3779 // no actual state changes have occurred, we should expect that the
3780 // service sorting order will not have changed.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003781 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003782}
3783
Christopher Wiley83889862013-05-02 15:55:09 -07003784TEST_F(ManagerTest, VerifyWhenNotConnected) {
3785 const string kFakeCertificate("fake cert");
3786 const string kFakePublicKey("fake public key");
3787 const string kFakeNonce("fake public key");
3788 const string kFakeSignedData("fake signed data");
3789 const string kFakeUdn("fake udn");
3790 const vector<uint8_t> kSSID(10, 87);
3791 const string kConfiguredSSID("AConfiguredDestination");
3792 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3793 kConfiguredSSID.end());
3794 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
3795 scoped_refptr<MockWiFiService> mock_destination(
3796 new NiceMock<MockWiFiService>(control_interface(), dispatcher(),
3797 metrics(), manager(), wifi_provider_,
3798 kSSID, "", "none", false));
3799 // Register this service, but don't mark it as connected.
3800 manager()->RegisterService(mock_destination);
3801 // Verify that if we're not connected to anything, verification fails.
3802 {
3803 LOG(INFO) << "Can't verify if not connected.";
3804 EXPECT_CALL(*crypto_util_proxy_,
3805 VerifyDestination(_, _, _, _, _, _, _, _, _)).Times(0);
3806 Error error(Error::kOperationInitiated);
3807 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3808 kFakeSignedData, kFakeUdn, "", "",
3809 ResultBoolCallback(), &error);
3810 EXPECT_TRUE(error.IsFailure());
3811 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3812 }
3813 {
3814 // However, if the destination is already configured, we might be
3815 // connected to it via something other than WiFi, and we shouldn't
3816 // enforce the WiFi check.
3817 EXPECT_CALL(*crypto_util_proxy_,
3818 VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3819 kFakeSignedData, kFakeUdn,
3820 kConfiguredSSIDVector, kConfiguredBSSID,
3821 _, _)).Times(1).WillOnce(Return(true));
3822 Error error(Error::kOperationInitiated);
3823 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3824 kFakeSignedData, kFakeUdn, kConfiguredSSID,
3825 kConfiguredBSSID, ResultBoolCallback(),
3826 &error);
3827 EXPECT_FALSE(error.IsFailure());
3828 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3829 }
3830}
3831
Christopher Wiley1057cd72013-02-28 15:21:29 -08003832TEST_F(ManagerTest, VerifyDestination) {
3833 const string kFakeCertificate("fake cert");
3834 const string kFakePublicKey("fake public key");
3835 const string kFakeNonce("fake public key");
3836 const string kFakeSignedData("fake signed data");
3837 const string kFakeUdn("fake udn");
3838 const char kSSIDStr[] = "fake ssid";
3839 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
Christopher Wileycdde79f2013-05-01 14:26:56 -07003840 const string kConfiguredSSID("AConfiguredDestination");
3841 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3842 kConfiguredSSID.end());
3843 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
Christopher Wiley1057cd72013-02-28 15:21:29 -08003844 const string kFakeData("muffin man");
3845 scoped_refptr<MockWiFiService> mock_destination(
3846 new NiceMock<MockWiFiService>(control_interface(),
3847 dispatcher(),
3848 metrics(),
3849 manager(),
3850 wifi_provider_,
3851 kSSID,
3852 "",
3853 "none",
3854 false));
3855 manager()->RegisterService(mock_destination);
Christopher Wiley1057cd72013-02-28 15:21:29 -08003856 // Making the service look online will let service lookup in
3857 // VerifyDestinatoin succeed.
3858 EXPECT_CALL(*mock_destination.get(), IsConnected())
3859 .WillRepeatedly(Return(true));
Christopher Wiley83889862013-05-02 15:55:09 -07003860 StrictMock<DestinationVerificationTest> dv_test;
Christopher Wiley1057cd72013-02-28 15:21:29 -08003861
3862 // Lead off by verifying that the basic VerifyDestination flow works.
3863 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003864 LOG(INFO) << "Basic VerifyDestination flow.";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003865 ResultBoolCallback passed_down_callback;
3866 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3867 kFakePublicKey,
3868 kFakeNonce,
3869 kFakeSignedData,
3870 kFakeUdn,
3871 kSSID,
3872 _,
3873 _,
3874 _))
3875 .Times(1)
3876 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3877 // Ask the manager to verify the current destination. This should look
3878 // up our previously registered service, and pass some metadata about
3879 // that service down to the CryptoUtilProxy to verify.
3880 Error error(Error::kOperationInitiated);
3881 ResultBoolCallback cb = Bind(
3882 &DestinationVerificationTest::ResultBoolCallbackStub,
3883 dv_test.AsWeakPtr());
3884 manager()->VerifyDestination(kFakeCertificate,
3885 kFakePublicKey,
3886 kFakeNonce,
3887 kFakeSignedData,
3888 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003889 // Ask to be verified against that service.
3890 "", "",
3891 cb,
3892 &error);
3893 // We assert here, because if the operation is not ongoing, it is
3894 // inconsistent with shim behavior to call the callback anyway.
3895 ASSERT_TRUE(error.IsOngoing());
3896 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3897 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3898 // Call the callback passed into the CryptoUtilProxy, which
3899 // should find its way into the callback passed into the manager.
3900 // In real code, that callback passed into the manager is from the
3901 // DBus adaptor.
3902 Error e;
3903 passed_down_callback.Run(e, true);
3904 Mock::VerifyAndClearExpectations(&dv_test);
3905 }
3906
Christopher Wiley1057cd72013-02-28 15:21:29 -08003907 // Now for a slightly more complex variant. When we encrypt data,
3908 // we do the same verification step but monkey with the callback to
3909 // link ourselves to an encrypt step afterward.
3910 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003911 LOG(INFO) << "Basic VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003912 ResultBoolCallback passed_down_callback;
3913 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3914 kFakePublicKey,
3915 kFakeNonce,
3916 kFakeSignedData,
3917 kFakeUdn,
3918 kSSID,
3919 _,
3920 _,
3921 _))
3922 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3923
3924 Error error(Error::kOperationInitiated);
3925 ResultStringCallback cb = Bind(
3926 &DestinationVerificationTest::ResultStringCallbackStub,
3927 dv_test.AsWeakPtr());
3928 manager()->VerifyAndEncryptData(kFakeCertificate,
3929 kFakePublicKey,
3930 kFakeNonce,
3931 kFakeSignedData,
3932 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003933 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003934 kFakeData,
3935 cb,
3936 &error);
3937 ASSERT_TRUE(error.IsOngoing());
3938 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3939 // Now, if we call that passed down callback, we should see encrypt being
3940 // called.
3941 ResultStringCallback second_passed_down_callback;
3942 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3943 kFakeData,
3944 _,
3945 _))
3946 .Times(1)
3947 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3948 Return(true)));
3949 Error e;
3950 passed_down_callback.Run(e, true);
3951 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3952 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3953 // And if we call the second passed down callback, we should see the
3954 // original function we passed down to VerifyDestination getting called.
3955 e.Reset();
3956 second_passed_down_callback.Run(e, "");
3957 Mock::VerifyAndClearExpectations(&dv_test);
3958 }
3959
3960 // If verification fails on the way to trying to encrypt, we should ditch
3961 // without calling encrypt at all.
3962 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003963 LOG(INFO) << "Failed VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003964 ResultBoolCallback passed_down_callback;
3965 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3966 kFakePublicKey,
3967 kFakeNonce,
3968 kFakeSignedData,
3969 kFakeUdn,
3970 kSSID,
3971 _,
3972 _,
3973 _))
3974 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3975
3976 Error error(Error::kOperationInitiated);
3977 ResultStringCallback cb = Bind(
3978 &DestinationVerificationTest::ResultStringCallbackStub,
3979 dv_test.AsWeakPtr());
3980 manager()->VerifyAndEncryptData(kFakeCertificate,
3981 kFakePublicKey,
3982 kFakeNonce,
3983 kFakeSignedData,
3984 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003985 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003986 kFakeData,
3987 cb,
3988 &error);
3989 ASSERT_TRUE(error.IsOngoing());
3990 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3991 Error e(Error::kOperationFailed);
3992 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3993 // Although we're ditching, this callback is what cleans up the pending
3994 // DBus call.
3995 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3996 passed_down_callback.Run(e, false);
3997 Mock::VerifyAndClearExpectations(&dv_test);
3998 }
3999}
4000
Paul Stewartd2e1c362013-03-03 19:06:07 -08004001TEST_F(ManagerTest, IsProfileBefore) {
4002 scoped_refptr<MockProfile> profile0(
4003 new NiceMock<MockProfile>(
4004 control_interface(), metrics(), manager(), ""));
4005 scoped_refptr<MockProfile> profile1(
4006 new NiceMock<MockProfile>(
4007 control_interface(), metrics(), manager(), ""));
4008
4009 AdoptProfile(manager(), profile0);
4010 AdoptProfile(manager(), profile1); // profile1 is after profile0.
4011 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
4012 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
4013
4014 // A few abnormal cases, but it's good to track their behavior.
4015 scoped_refptr<MockProfile> profile2(
4016 new NiceMock<MockProfile>(
4017 control_interface(), metrics(), manager(), ""));
4018 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
4019 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
4020 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
4021 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
4022}
4023
Paul Stewart967eaeb2013-04-25 19:53:07 -07004024TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
4025 MockStore storage0;
4026 MockStore storage1;
4027 MockStore storage2;
4028
4029 scoped_refptr<MockProfile> profile0(
4030 new NiceMock<MockProfile>(
4031 control_interface(), metrics(), manager(), ""));
4032 scoped_refptr<MockProfile> profile1(
4033 new NiceMock<MockProfile>(
4034 control_interface(), metrics(), manager(), ""));
4035 scoped_refptr<MockProfile> profile2(
4036 new NiceMock<MockProfile>(
4037 control_interface(), metrics(), manager(), ""));
4038
4039 AdoptProfile(manager(), profile0);
4040 AdoptProfile(manager(), profile1);
4041 AdoptProfile(manager(), profile2);
4042
4043 scoped_refptr<MockService> service(
4044 new NiceMock<MockService>(control_interface(),
4045 dispatcher(),
4046 metrics(),
4047 manager()));
4048
4049 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
4050 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
4051 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
4052
4053 const string kEntry0("aluminum_crutch");
4054 const string kEntry2("rehashed_faces");
4055
4056 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
4057 .WillOnce(Return(kEntry0));
4058 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
4059 .WillOnce(Return(""));
4060 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
4061 .WillOnce(Return(kEntry2));
4062
4063 const string kProfileRpc0("service_station");
4064 const string kProfileRpc2("crystal_tiaras");
4065
4066 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
4067 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
4068 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
4069
4070 map<string, string> entries =
4071 manager()->GetLoadableProfileEntriesForService(service);
4072 EXPECT_EQ(2, entries.size());
4073 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
4074 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
4075 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
4076 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
4077}
4078
mukesh agrawal00752532013-05-03 15:46:55 -07004079TEST_F(ManagerTest, InitializeProfilesInformsProviders) {
mukesh agrawald142fd62013-05-01 16:50:57 -07004080 // We need a real glib here, so that profiles are persisted.
4081 GLib glib;
4082 ScopedTempDir temp_dir;
4083 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4084 Manager manager(control_interface(),
4085 dispatcher(),
4086 metrics(),
4087 &glib,
4088 run_path(),
4089 storage_path(),
4090 temp_dir.path().value());
4091 // Can't use |wifi_provider_|, because it's owned by the Manager
4092 // object in the fixture.
4093 MockWiFiProvider *wifi_provider = new NiceMock<MockWiFiProvider>();
4094 manager.wifi_provider_.reset(wifi_provider); // pass ownership
Paul Stewartb87d22b2013-07-29 11:11:37 -07004095 manager.UpdateProviderMapping();
mukesh agrawald142fd62013-05-01 16:50:57 -07004096 // Give manager a valid place to write the user profile list.
4097 manager.user_profile_list_path_ = temp_dir.path().Append("user_profile_list");
4098
4099 // With no user profiles, the WiFiProvider should be called once
4100 // (for the default profile).
4101 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_));
4102 manager.InitializeProfiles();
4103 Mock::VerifyAndClearExpectations(wifi_provider);
4104
4105 // With |n| user profiles, the WiFiProvider should be called |n+1|
4106 // times. First, create 2 user profiles...
4107 const char kProfile0[] = "~user/profile0";
4108 const char kProfile1[] = "~user/profile1";
4109 string profile_rpc_path;
4110 Error error;
mukesh agrawal0a59a5a2014-04-24 19:10:46 -07004111 ASSERT_TRUE(base::CreateDirectory(temp_dir.path().Append("user")));
mukesh agrawald142fd62013-05-01 16:50:57 -07004112 manager.CreateProfile(kProfile0, &profile_rpc_path, &error);
4113 manager.PushProfile(kProfile0, &profile_rpc_path, &error);
4114 manager.CreateProfile(kProfile1, &profile_rpc_path, &error);
4115 manager.PushProfile(kProfile1, &profile_rpc_path, &error);
4116
4117 // ... then reset manager state ...
4118 manager.profiles_.clear();
4119
4120 // ...then check that the WiFiProvider is notified about all three
4121 // profiles (one default, two user).
4122 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_)).Times(3);
4123 manager.InitializeProfiles();
4124 Mock::VerifyAndClearExpectations(wifi_provider);
4125}
4126
mukesh agrawal00752532013-05-03 15:46:55 -07004127TEST_F(ManagerTest, InitializeProfilesHandlesDefaults) {
4128 // We need a real glib here, so that profiles are persisted.
4129 GLib glib;
4130 ScopedTempDir temp_dir;
4131 scoped_ptr<Manager> manager;
4132 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4133
4134 // Instantiate a Manager with empty persistent storage. Check that
4135 // defaults are set.
4136 //
4137 // Note that we use the same directory for default and user profiles.
4138 // This doesn't affect the test results, because we don't push a
4139 // user profile.
4140 manager.reset(new Manager(control_interface(),
4141 dispatcher(),
4142 metrics(),
4143 &glib,
4144 run_path(),
4145 temp_dir.path().value(),
4146 temp_dir.path().value()));
4147 manager->InitializeProfiles();
4148 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4149 manager->props_.check_portal_list);
4150 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
4151 manager->props_.ignored_dns_search_paths);
4152 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
4153 manager->props_.link_monitor_technologies);
4154 EXPECT_EQ(PortalDetector::kDefaultURL,
4155 manager->props_.portal_url);
4156 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
4157 manager->props_.portal_check_interval_seconds);
4158
4159 // Change one of the settings.
4160 static const string kCustomCheckPortalList = "fiber0";
4161 Error error;
4162 manager->SetCheckPortalList(kCustomCheckPortalList, &error);
4163 manager->profiles_[0]->Save();
4164
4165 // Instantiate a new manager. It should have our settings for
4166 // check_portal_list, rather than the default.
4167 manager.reset(new Manager(control_interface(),
4168 dispatcher(),
4169 metrics(),
4170 &glib,
4171 run_path(),
4172 temp_dir.path().value(),
4173 temp_dir.path().value()));
4174 manager->InitializeProfiles();
4175 EXPECT_EQ(kCustomCheckPortalList, manager->props_.check_portal_list);
4176
4177 // If we clear the persistent storage, we again get the default value.
4178 ASSERT_TRUE(temp_dir.Delete());
4179 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4180 manager.reset(new Manager(control_interface(),
4181 dispatcher(),
4182 metrics(),
4183 &glib,
4184 run_path(),
4185 temp_dir.path().value(),
4186 temp_dir.path().value()));
4187 manager->InitializeProfiles();
4188 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4189 manager->props_.check_portal_list);
4190}
4191
mukesh agrawalb94adde2013-08-22 18:17:26 -07004192TEST_F(ManagerTest, ProfileStackChangeLogging) {
4193 // We use a real glib here, since Manager and Profile don't provide an
4194 // easy way to mock out KeyFileStore.
4195 GLib glib;
4196 ScopedTempDir temp_dir;
4197 scoped_ptr<Manager> manager;
4198 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4199 manager.reset(new Manager(control_interface(),
4200 dispatcher(),
4201 metrics(),
4202 &glib,
4203 run_path(),
4204 temp_dir.path().value(),
4205 temp_dir.path().value()));
4206
4207 ScopedMockLog log;
4208 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
4209 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("1 profile(s)")));
4210 manager->InitializeProfiles();
4211
4212 const char kProfile0[] = "~user/profile0";
4213 const char kProfile1[] = "~user/profile1";
4214 const char kProfile2[] = "~user/profile2";
mukesh agrawal0a59a5a2014-04-24 19:10:46 -07004215 ASSERT_TRUE(base::CreateDirectory(temp_dir.path().Append("user")));
mukesh agrawalb94adde2013-08-22 18:17:26 -07004216 TestCreateProfile(manager.get(), kProfile0);
4217 TestCreateProfile(manager.get(), kProfile1);
4218 TestCreateProfile(manager.get(), kProfile2);
4219
4220 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("2 profile(s)")));
4221 TestPushProfile(manager.get(), kProfile0);
4222
4223 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("3 profile(s)")));
4224 TestInsertUserProfile(manager.get(), kProfile1, "not-so-random-string");
4225
4226 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("4 profile(s)")));
4227 TestInsertUserProfile(manager.get(), kProfile2, "very-random-string");
4228
4229 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("3 profile(s)")));
4230 TestPopProfile(manager.get(), kProfile2);
4231
4232 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("2 profile(s)")));
4233 TestPopAnyProfile(manager.get());
4234
4235 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("1 profile(s)")));
4236 TestPopAllUserProfiles(manager.get());
4237}
4238
mukesh agrawalbebf1b82013-04-23 15:06:33 -07004239// Custom property setters should return false, and make no changes, if
4240// the new value is the same as the old value.
4241TEST_F(ManagerTest, CustomSetterNoopChange) {
4242 // SetCheckPortalList
4243 {
4244 static const string kCheckPortalList = "weird-device,weirder-device";
4245 Error error;
4246 // Set to known value.
4247 EXPECT_TRUE(SetCheckPortalList(kCheckPortalList, &error));
4248 EXPECT_TRUE(error.IsSuccess());
4249 // Set to same value.
4250 EXPECT_FALSE(SetCheckPortalList(kCheckPortalList, &error));
4251 EXPECT_TRUE(error.IsSuccess());
4252 }
4253
4254 // SetIgnoredDNSSearchPaths
4255 {
4256 NiceMock<MockResolver> resolver;
4257 static const string kIgnoredPaths = "example.com,example.org";
4258 Error error;
4259 SetResolver(&resolver);
4260 // Set to known value.
4261 EXPECT_CALL(resolver, set_ignored_search_list(_));
4262 EXPECT_TRUE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4263 EXPECT_TRUE(error.IsSuccess());
4264 Mock::VerifyAndClearExpectations(&resolver);
4265 // Set to same value.
4266 EXPECT_CALL(resolver, set_ignored_search_list(_)).Times(0);
4267 EXPECT_FALSE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4268 EXPECT_TRUE(error.IsSuccess());
4269 Mock::VerifyAndClearExpectations(&resolver);
4270 }
4271}
4272
Paul Stewart7de7e022013-08-28 09:42:50 -07004273TEST_F(ManagerTest, GeoLocation) {
4274 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4275
4276 auto device = make_scoped_refptr(new NiceMock<MockDevice>(control_interface(),
4277 dispatcher(),
4278 metrics(),
4279 manager(),
4280 "null",
4281 "addr",
4282 0));
4283
4284 // Manager should ignore gelocation info from technologies it does not know.
4285 EXPECT_CALL(*device, technology())
4286 .Times(AtLeast(1))
4287 .WillRepeatedly(Return(Technology::kEthernet));
4288 EXPECT_CALL(*device, GetGeolocationObjects()).Times(0);
4289 manager()->OnDeviceGeolocationInfoUpdated(device);
4290 Mock::VerifyAndClearExpectations(device);
4291 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4292
4293 // Manager should add WiFi geolocation info.
4294 EXPECT_CALL(*device, technology())
4295 .Times(AtLeast(1))
4296 .WillRepeatedly(Return(Technology::kWifi));
4297 EXPECT_CALL(*device, GetGeolocationObjects())
4298 .WillOnce(Return(vector<GeolocationInfo>()));
4299 manager()->OnDeviceGeolocationInfoUpdated(device);
4300 Mock::VerifyAndClearExpectations(device);
4301 auto location_infos = manager()->GetNetworksForGeolocation();
4302 EXPECT_EQ(1, location_infos.size());
4303 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4304
4305 // Manager should inclusively add cellular info.
4306 EXPECT_CALL(*device, technology())
4307 .Times(AtLeast(1))
4308 .WillRepeatedly(Return(Technology::kCellular));
4309 EXPECT_CALL(*device, GetGeolocationObjects())
4310 .WillOnce(Return(vector<GeolocationInfo>()));
4311 manager()->OnDeviceGeolocationInfoUpdated(device);
4312 location_infos = manager()->GetNetworksForGeolocation();
4313 EXPECT_EQ(2, location_infos.size());
4314 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4315 EXPECT_TRUE(ContainsKey(location_infos, kGeoCellTowersProperty));
4316}
4317
Peter Qiu574996a2014-04-04 10:55:47 -07004318TEST_F(ManagerTest, IsWifiIdle) {
4319 // No registered service.
4320 EXPECT_FALSE(manager()->IsWifiIdle());
4321
4322 scoped_refptr<MockService> wifi_service(new MockService(control_interface(),
4323 dispatcher(),
4324 metrics(),
4325 manager()));
4326
4327 scoped_refptr<MockService> cell_service(new MockService(control_interface(),
4328 dispatcher(),
4329 metrics(),
4330 manager()));
4331
4332 manager()->RegisterService(wifi_service);
4333 manager()->RegisterService(cell_service);
4334
4335 EXPECT_CALL(*wifi_service.get(), technology())
4336 .WillRepeatedly(Return(Technology::kWifi));
4337 EXPECT_CALL(*cell_service.get(), technology())
4338 .WillRepeatedly(Return(Technology::kCellular));
4339
4340 // Cellular is connected.
4341 EXPECT_CALL(*cell_service.get(), IsConnected())
4342 .WillRepeatedly(Return(true));
4343 manager()->UpdateService(cell_service);
4344
4345 // No wifi connection attempt.
4346 EXPECT_CALL(*wifi_service.get(), IsConnecting())
4347 .WillRepeatedly(Return(false));
4348 EXPECT_CALL(*wifi_service.get(), IsConnected())
4349 .WillRepeatedly(Return(false));
4350 manager()->UpdateService(wifi_service);
4351 EXPECT_TRUE(manager()->IsWifiIdle());
4352
4353 // Attempt wifi connection.
4354 Mock::VerifyAndClearExpectations(wifi_service);
4355 EXPECT_CALL(*wifi_service.get(), technology())
4356 .WillRepeatedly(Return(Technology::kWifi));
4357 EXPECT_CALL(*wifi_service.get(), IsConnecting())
4358 .WillRepeatedly(Return(true));
4359 EXPECT_CALL(*wifi_service.get(), IsConnected())
4360 .WillRepeatedly(Return(false));
4361 manager()->UpdateService(wifi_service);
4362 EXPECT_FALSE(manager()->IsWifiIdle());
4363
4364 // wifi connected.
4365 Mock::VerifyAndClearExpectations(wifi_service);
4366 EXPECT_CALL(*wifi_service.get(), technology())
4367 .WillRepeatedly(Return(Technology::kWifi));
4368 EXPECT_CALL(*wifi_service.get(), IsConnecting())
4369 .WillRepeatedly(Return(false));
4370 EXPECT_CALL(*wifi_service.get(), IsConnected())
4371 .WillRepeatedly(Return(true));
4372 manager()->UpdateService(wifi_service);
4373 EXPECT_FALSE(manager()->IsWifiIdle());
4374}
4375
Chris Masone9be4a9d2011-05-16 15:44:09 -07004376} // namespace shill