blob: 8fe7bec5bae1c8b5693d96fdaf780c65e68ae12b [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07004
5#include "shill/manager.h"
6
Jason Glasgowdf7c5532012-05-14 14:41:45 -04007#include <map>
Chris Masone6791a432011-07-12 13:23:19 -07008#include <set>
9
Chris Masone9be4a9d2011-05-16 15:44:09 -070010#include <glib.h>
11
Paul Stewarte73d05c2012-03-29 16:26:05 -070012#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080013#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070015#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070017#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070018#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070019
mukesh agrawal32399322011-09-01 10:53:43 -070020#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070021#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070022#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070023#include "shill/glib.h"
24#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070025#include "shill/key_value_store.h"
mukesh agrawal00752532013-05-03 15:46:55 -070026#include "shill/link_monitor.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070027#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070028#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080029#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070030#include "shill/mock_control.h"
Christopher Wiley1057cd72013-02-28 15:21:29 -080031#include "shill/mock_crypto_util_proxy.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070032#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080033#include "shill/mock_device_info.h"
Paul Stewart35eff132013-04-12 12:08:40 -070034#include "shill/mock_ethernet_eap_provider.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070035#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000036#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020037#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070038#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070039#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070040#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070041#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080042#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070043#include "shill/mock_wifi_service.h"
mukesh agrawal00752532013-05-03 15:46:55 -070044#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070045#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020046#include "shill/proxy_factory.h"
mukesh agrawal00752532013-05-03 15:46:55 -070047#include "shill/resolver.h"
Chris Masone6515aab2011-10-12 16:19:09 -070048#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070049#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020050#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070051
Christopher Wiley1057cd72013-02-28 15:21:29 -080052using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080053using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080054using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070055using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070056using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057using std::string;
58using std::vector;
59
Chris Masone9be4a9d2011-05-16 15:44:09 -070060namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070061using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070062using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080063using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070064using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070065using ::testing::InSequence;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070066using ::testing::Invoke;
mukesh agrawal784566d2012-08-08 18:32:58 -070067using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070068using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070069using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070070using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070071using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070072using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070073using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080074using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080075using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080076using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070077using ::testing::Test;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070078using ::testing::WithArg;
Chris Masone9be4a9d2011-05-16 15:44:09 -070079
Chris Masone3bd3c8c2011-06-13 08:20:26 -070080class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070081 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070082 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020083 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080084 device_info_(new NiceMock<MockDeviceInfo>(
85 control_interface(),
86 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080087 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080088 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080089 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070090 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080091 wifi_provider_(new NiceMock<MockWiFiProvider>()),
92 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
93 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070094 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
95 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080096 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070097 manager(),
98 "null0",
99 "addr0",
100 0));
101 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
102 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800103 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700104 manager(),
105 "null1",
106 "addr1",
107 1));
108 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
109 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800110 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700111 manager(),
112 "null2",
113 "addr2",
114 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800115 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
116 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800117 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800118 manager(),
119 "null3",
120 "addr3",
121 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700122 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800123 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800124
125 // Replace the manager's adaptor with a quieter one, and one
126 // we can do EXPECT*() against. Passes ownership.
127 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800128
Paul Stewart35eff132013-04-12 12:08:40 -0700129 // Replace the manager's Ethernet EAP provider with our mock.
130 // Passes ownership.
131 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
132
Paul Stewart3c504012013-01-17 17:49:58 -0800133 // Replace the manager's WiFi provider with our mock. Passes
134 // ownership.
135 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800136
Paul Stewartb87d22b2013-07-29 11:11:37 -0700137 // Update the manager's map from technology to provider.
138 manager()->UpdateProviderMapping();
139
Christopher Wiley1057cd72013-02-28 15:21:29 -0800140 // Replace the manager's crypto util proxy with our mock. Passes
141 // ownership.
142 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Paul Stewart9dd253e2013-04-22 08:32:59 -0700143
144 // Reset service serial number so service sorting by unique_name()
145 // (and by extension, sorting by order of creation) is predictable.
146 Service::serial_number_ = 10000;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700147 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700148 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700149
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100150 void SetMetrics(Metrics *metrics) {
151 manager()->set_metrics(metrics);
152 }
153
Paul Stewartfdd16072011-09-16 12:41:35 -0700154 bool IsDeviceRegistered(const DeviceRefPtr &device,
155 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700156 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700157 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700158 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700159 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700160 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700161
Paul Stewarta849a3d2011-11-03 05:54:09 -0700162 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
163 manager->profiles_.push_back(profile);
164 }
165
Paul Stewart63864b62012-11-07 15:10:55 -0800166 void SetRunning(bool running) {
167 manager()->running_ = running;
168 }
169
Paul Stewart75225512012-01-26 22:51:33 -0800170 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
171 return manager->ephemeral_profile_;
172 }
173
Paul Stewart307c2502013-03-23 12:32:10 -0700174 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
175 return manager->profiles_;
176 }
177
Chris Masone6515aab2011-10-12 16:19:09 -0700178 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
179 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700180 FilePath final_path(storage_path());
181 final_path = final_path.Append("test.profile");
182 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
183 storage->set_path(final_path);
184 if (!storage->Open())
185 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800186 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800187 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800188 manager,
189 id,
190 "",
191 false));
192 profile->set_storage(storage.release()); // Passes ownership of "storage".
193 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700194 }
195
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700196 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
197 const string &profile_identifier,
198 const string &service_name) {
199 GLib glib;
200 KeyFileStore store(&glib);
201 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
202 return store.Open() &&
203 store.SetString(service_name, "rather", "irrelevant") &&
204 store.Close();
205 }
206
207 Error::Type TestCreateProfile(Manager *manager, const string &name) {
208 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800209 string path;
210 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700211 return error.type();
212 }
213
214 Error::Type TestPopAnyProfile(Manager *manager) {
215 Error error;
216 manager->PopAnyProfile(&error);
217 return error.type();
218 }
219
Paul Stewart307c2502013-03-23 12:32:10 -0700220 Error::Type TestPopAllUserProfiles(Manager *manager) {
221 Error error;
222 manager->PopAllUserProfiles(&error);
223 return error.type();
224 }
225
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700226 Error::Type TestPopProfile(Manager *manager, const string &name) {
227 Error error;
228 manager->PopProfile(name, &error);
229 return error.type();
230 }
231
232 Error::Type TestPushProfile(Manager *manager, const string &name) {
233 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800234 string path;
235 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700236 return error.type();
237 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000238
Paul Stewartf3eced92013-04-17 12:18:22 -0700239 Error::Type TestInsertUserProfile(Manager *manager,
240 const string &name,
241 const string &user_hash) {
242 Error error;
243 string path;
244 manager->InsertUserProfile(name, user_hash, &path, &error);
245 return error.type();
246 }
247
Paul Stewartd2e1c362013-03-03 19:06:07 -0800248 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
249 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700250 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800251 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800252 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200253 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700254 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800255 return profile;
256 }
257
258 void AddMockProfileToManager(Manager *manager) {
259 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700260 }
261
Paul Stewartdfa46052012-06-26 09:44:14 -0700262 void CompleteServiceSort() {
263 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
264 dispatcher()->DispatchPendingEvents();
265 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
266 }
267
Paul Stewart49739c02012-08-08 17:24:03 -0700268 RpcIdentifier GetDefaultServiceRpcIdentifier() {
269 return manager()->GetDefaultServiceRpcIdentifier(NULL);
270 }
271
Paul Stewart4d5efb72012-09-17 12:24:34 -0700272 void SetResolver(Resolver *resolver) {
273 manager()->resolver_ = resolver;
274 }
275
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700276 bool SetIgnoredDNSSearchPaths(const string &search_paths, Error *error) {
277 return manager()->SetIgnoredDNSSearchPaths(search_paths, error);
278 }
279
280 bool SetCheckPortalList(const string &check_portal_list, Error *error) {
281 return manager()->SetCheckPortalList(check_portal_list, error);
Paul Stewart4d5efb72012-09-17 12:24:34 -0700282 }
283
284 const string &GetIgnoredDNSSearchPaths() {
285 return manager()->props_.ignored_dns_search_paths;
286 }
287
Paul Stewartd2e1c362013-03-03 19:06:07 -0800288 WiFiServiceRefPtr ReleaseTempMockService() {
289 // Take a reference to hold during this function.
290 WiFiServiceRefPtr temp_service = temp_mock_service_;
291 temp_mock_service_ = NULL;
292 return temp_service;
293 }
294
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700295 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000296 typedef scoped_refptr<MockService> MockServiceRefPtr;
297
Darin Petkova5e07ef2012-07-09 14:27:57 +0200298 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
299 public:
300 ServiceWatcher() {}
301 virtual ~ServiceWatcher() {}
302
303 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
304
305 private:
306 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
307 };
308
Darin Petkovca621542012-07-25 14:25:56 +0200309 class TestProxyFactory : public ProxyFactory {
310 public:
311 TestProxyFactory() {}
312
313 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
314 PowerManagerProxyDelegate */*delegate*/) {
315 return NULL;
316 }
317
318 private:
319 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
320 };
321
Darin Petkov3ec55342012-09-28 14:04:44 +0200322 class TerminationActionTest :
323 public base::SupportsWeakPtr<TerminationActionTest> {
324 public:
325 static const char kActionName[];
326
327 TerminationActionTest() : manager_(NULL) {}
328 virtual ~TerminationActionTest() {}
329
330 MOCK_METHOD1(Done, void(const Error &error));
331
332 void Action() {
333 manager_->TerminationActionComplete("action");
334 }
335
336 void set_manager(Manager *manager) { manager_ = manager; }
337
338 private:
339 Manager *manager_;
340 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
341 };
342
Christopher Wiley1057cd72013-02-28 15:21:29 -0800343 class DestinationVerificationTest :
344 public base::SupportsWeakPtr<DestinationVerificationTest> {
345 public:
346 DestinationVerificationTest() {}
347 virtual ~DestinationVerificationTest() {}
348
349 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
350 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
351 const string &value));
352 private:
353 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
354 };
355
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700356 class DisableTechnologyReplyHandler :
357 public base::SupportsWeakPtr<DisableTechnologyReplyHandler> {
358 public:
359 DisableTechnologyReplyHandler() {}
360 virtual ~DisableTechnologyReplyHandler() {}
361
362 MOCK_METHOD1(ReportResult, void(const Error &));
363
364 private:
365 DISALLOW_COPY_AND_ASSIGN(DisableTechnologyReplyHandler);
366 };
367
Darin Petkovca621542012-07-25 14:25:56 +0200368 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
369 power_manager_->power_state_ = state;
370 }
371
372 void SetPowerManager() {
373 manager()->set_power_manager(power_manager_.release());
374 }
375
Darin Petkov3ec55342012-09-28 14:04:44 +0200376 HookTable *GetTerminationActions() {
377 return &manager()->termination_actions_;
378 }
379
Darin Petkovca621542012-07-25 14:25:56 +0200380 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
381 manager()->OnPowerStateChanged(state);
382 }
383
Daniel Erat0818cca2012-12-14 10:16:21 -0800384 void OnSuspendImminent(int suspend_id) {
385 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200386 }
387
Daniel Erat0818cca2012-12-14 10:16:21 -0800388 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
389 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200390 }
391
Paul Stewartbfb82552012-10-24 16:48:48 -0700392 vector<string> EnumerateAvailableServices() {
393 return manager()->EnumerateAvailableServices(NULL);
394 }
395
396 vector<string> EnumerateWatchedServices() {
397 return manager()->EnumerateWatchedServices(NULL);
398 }
399
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000400 MockServiceRefPtr MakeAutoConnectableService() {
401 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
402 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800403 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000404 manager());
405 service->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700406 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000407 return service;
408 }
409
Paul Stewart35eff132013-04-12 12:08:40 -0700410 void SetEapProviderService(const ServiceRefPtr &service) {
411 ethernet_eap_provider_->set_service(service);
412 }
413
Darin Petkovca621542012-07-25 14:25:56 +0200414 TestProxyFactory proxy_factory_;
415 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700416 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800417 scoped_ptr<MockDeviceInfo> device_info_;
418
Paul Stewartd2e1c362013-03-03 19:06:07 -0800419 // This service is held for the manager, and given ownership in a mock
420 // function. This ensures that when the Manager takes ownership, there
421 // is only one reference left.
422 scoped_refptr<MockWiFiService> temp_mock_service_;
423
Paul Stewart3c504012013-01-17 17:49:58 -0800424 // These pointers are owned by the manager, and only tracked here for
425 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800426 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700427 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800428 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800429 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700430};
431
Darin Petkov3ec55342012-09-28 14:04:44 +0200432const char ManagerTest::TerminationActionTest::kActionName[] = "action";
433
Paul Stewart22aa71b2011-09-16 12:15:11 -0700434bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700435 if (!manager()->sort_services_task_.IsCancelled()) {
436 manager()->SortServicesTask();
437 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700438 return (svc0.get() == manager()->services_[0].get() &&
439 svc1.get() == manager()->services_[1].get());
440}
441
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700442void SetErrorPermissionDenied(Error *error) {
443 error->Populate(Error::kPermissionDenied);
444}
445
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700446TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700447 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
448 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700449}
450
Chris Masone9be4a9d2011-05-16 15:44:09 -0700451TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700452 ON_CALL(*mock_devices_[0].get(), technology())
453 .WillByDefault(Return(Technology::kEthernet));
454 ON_CALL(*mock_devices_[1].get(), technology())
455 .WillByDefault(Return(Technology::kWifi));
456 ON_CALL(*mock_devices_[2].get(), technology())
457 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700458
Paul Stewart22aa71b2011-09-16 12:15:11 -0700459 manager()->RegisterDevice(mock_devices_[0]);
460 manager()->RegisterDevice(mock_devices_[1]);
461 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700462
Paul Stewart22aa71b2011-09-16 12:15:11 -0700463 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
464 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
465 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700466}
467
Paul Stewarta41e38d2011-11-11 07:47:29 -0800468TEST_F(ManagerTest, DeviceRegistrationAndStart) {
469 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500470 mock_devices_[0]->enabled_persistent_ = true;
471 mock_devices_[1]->enabled_persistent_ = false;
472 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800473 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500474 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800475 .Times(0);
476 manager()->RegisterDevice(mock_devices_[0]);
477 manager()->RegisterDevice(mock_devices_[1]);
478}
479
480TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800481 MockProfile *profile =
482 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800483 DeviceRefPtr device_ref(mock_devices_[0].get());
484 AdoptProfile(manager(), profile); // Passes ownership.
485 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200486 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800487 manager()->RegisterDevice(mock_devices_[0]);
488}
489
Chris Masone9be4a9d2011-05-16 15:44:09 -0700490TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700491 ON_CALL(*mock_devices_[0].get(), technology())
492 .WillByDefault(Return(Technology::kEthernet));
493 ON_CALL(*mock_devices_[1].get(), technology())
494 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700495
Gaurav Shah435de2c2011-11-17 19:01:07 -0800496 manager()->RegisterDevice(mock_devices_[0]);
497 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700498
Paul Stewart22aa71b2011-09-16 12:15:11 -0700499 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
500 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700501
Thieu Le5133b712013-02-19 14:47:21 -0800502 MockProfile *profile =
503 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700504 AdoptProfile(manager(), profile); // Passes ownership.
505
Eric Shienbrood9a245532012-03-07 14:20:39 -0500506 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700507 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800508 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700509 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700510
Eric Shienbrood9a245532012-03-07 14:20:39 -0500511 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700512 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800513 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700514 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700515}
516
517TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700518 // It's much easier and safer to use a real GLib for this test.
519 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700520 Manager manager(control_interface(),
521 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800522 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700523 &glib,
524 run_path(),
525 storage_path(),
526 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700527 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
528 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700529 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700530
Chris Masone9be4a9d2011-05-16 15:44:09 -0700531 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700532 new NiceMock<MockService>(control_interface(),
533 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800534 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700535 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700536 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700537 new NiceMock<MockService>(control_interface(),
538 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800539 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700540 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700541
Darin Petkov457728b2013-01-09 09:49:08 +0100542 string service1_name(mock_service->unique_name());
543 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700544
545 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
546 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700547 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700548 .WillRepeatedly(Return(service2_name));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700549 // TODO(quiche): make this EXPECT_CALL work (crbug.com/203247)
Chris Masone9d779932011-08-25 16:33:41 -0700550 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700551 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700552
Chris Masone9d779932011-08-25 16:33:41 -0700553 manager.RegisterService(mock_service);
554 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700555
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800556 Error error;
557 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700558 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700559 EXPECT_EQ(2, ids.size());
560 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
561 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700562
Chris Masone9d779932011-08-25 16:33:41 -0700563 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
564 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
565
566 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700567}
568
Chris Masone6515aab2011-10-12 16:19:09 -0700569TEST_F(ManagerTest, RegisterKnownService) {
570 // It's much easier and safer to use a real GLib for this test.
571 GLib glib;
572 Manager manager(control_interface(),
573 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800574 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700575 &glib,
576 run_path(),
577 storage_path(),
578 string());
579 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
580 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700581 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700582 {
583 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
584 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800585 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700586 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700587 ASSERT_TRUE(profile->AdoptService(service1));
588 ASSERT_TRUE(profile->ContainsService(service1));
589 } // Force destruction of service1.
590
591 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
592 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800593 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700594 &manager));
595 manager.RegisterService(service2);
596 EXPECT_EQ(service2->profile().get(), profile.get());
597 manager.Stop();
598}
599
600TEST_F(ManagerTest, RegisterUnknownService) {
601 // It's much easier and safer to use a real GLib for this test.
602 GLib glib;
603 Manager manager(control_interface(),
604 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800605 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700606 &glib,
607 run_path(),
608 storage_path(),
609 string());
610 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
611 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700612 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700613 {
614 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
615 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800616 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700617 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700618 ASSERT_TRUE(profile->AdoptService(service1));
619 ASSERT_TRUE(profile->ContainsService(service1));
620 } // Force destruction of service1.
621 scoped_refptr<MockService> mock_service2(
622 new NiceMock<MockService>(control_interface(),
623 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800624 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700625 &manager));
626 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100627 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700628 manager.RegisterService(mock_service2);
629 EXPECT_NE(mock_service2->profile().get(), profile.get());
630 manager.Stop();
631}
632
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000633TEST_F(ManagerTest, DeregisterUnregisteredService) {
634 // WiFi assumes that it can deregister a service that is not
635 // registered. (E.g. a hidden service can be deregistered when it
636 // loses its last endpoint, and again when WiFi is Stop()-ed.)
637 //
638 // So test that doing so doesn't cause a crash.
639 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
640 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800641 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000642 manager());
643 manager()->DeregisterService(service);
644}
645
Chris Masonea8a2c252011-06-27 22:16:30 -0700646TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700647 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700648 map<string, ::DBus::Variant> props;
649 Error error(Error::kInvalidProperty, "");
650 {
651 ::DBus::Error dbus_error;
652 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700653 manager()->mutable_store()->SetStringProperty(
654 flimflam::kCheckPortalListProperty,
655 expected,
656 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700657 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700658 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
659 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
660 expected);
661 }
662 {
663 ::DBus::Error dbus_error;
664 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700665 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
666 expected,
667 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700668 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700669 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
670 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
671 expected);
672 }
673}
674
Chris Masone3c3f6a12011-07-01 10:01:41 -0700675TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700676 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800677 manager()->RegisterDevice(mock_devices_[0]);
678 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700679 {
680 map<string, ::DBus::Variant> props;
681 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700682 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700683 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700684 vector < ::DBus::Path> devices =
685 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700686 EXPECT_EQ(2, devices.size());
687 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700688}
689
mukesh agrawal2366eed2012-03-20 18:21:50 -0700690TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700691 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700692 map<string, ::DBus::Variant> props;
693 ::DBus::Error dbus_error;
694 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
695 map<string, ::DBus::Variant>::const_iterator prop =
696 props.find(flimflam::kServicesProperty);
697 ASSERT_FALSE(prop == props.end());
698 const ::DBus::Variant &variant = prop->second;
699 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
700}
701
Chris Masone6791a432011-07-12 13:23:19 -0700702TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700703 Manager manager(control_interface(),
704 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800705 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700706 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700707 run_path(),
708 storage_path(),
709 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700710 scoped_refptr<MockService> s2(new MockService(control_interface(),
711 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800712 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700713 &manager));
714 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700715 {
Chris Masone6515aab2011-10-12 16:19:09 -0700716 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700717 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800718 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700719 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700720 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700721 .WillRepeatedly(Return(true));
722 EXPECT_CALL(*storage, Flush())
723 .Times(AnyNumber())
724 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700725 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700726 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700727 }
Chris Masone6515aab2011-10-12 16:19:09 -0700728 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800729 ProfileRefPtr profile(
730 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700731 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700732
Chris Masone6515aab2011-10-12 16:19:09 -0700733 // Now, move the Service |s2| to another profile.
734 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
735 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700736
737 // Force destruction of the original Profile, to ensure that the Service
738 // is kept alive and populated with data.
739 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700740 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700741 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700742}
743
Paul Stewart7f61e522012-03-22 11:13:45 -0700744TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
745 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800746 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700747 const string kProfileName("profile0");
748 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
749 .WillRepeatedly(Return(kProfileName));
750 AdoptProfile(manager(), mock_profile);
751
752 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
753 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
754 EXPECT_EQ(mock_profile.get(), profile.get());
755}
756
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800757TEST_F(ManagerTest, SetProfileForService) {
758 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800759 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800760 string profile_name0("profile0");
761 EXPECT_CALL(*profile0, GetRpcIdentifier())
762 .WillRepeatedly(Return(profile_name0));
763 AdoptProfile(manager(), profile0);
764 scoped_refptr<MockService> service(new MockService(control_interface(),
765 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800766 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800767 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700768 EXPECT_FALSE(manager()->HasService(service));
769 {
770 Error error;
771 EXPECT_CALL(*profile0, AdoptService(_))
772 .WillOnce(Return(true));
773 // Expect that setting the profile of a service that does not already
774 // have one assigned does not cause a crash.
775 manager()->SetProfileForService(service, "profile0", &error);
776 EXPECT_TRUE(error.IsSuccess());
777 }
778
779 // The service should be registered as a side-effect of the profile being
780 // set for this service.
781 EXPECT_TRUE(manager()->HasService(service));
782
783 // Since we have mocked Profile::AdoptServie() above, the service's
784 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800785 service->set_profile(profile0);
786
787 {
788 Error error;
789 manager()->SetProfileForService(service, "foo", &error);
790 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700791 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800792 }
793
794 {
795 Error error;
796 manager()->SetProfileForService(service, profile_name0, &error);
797 EXPECT_EQ(Error::kInvalidArguments, error.type());
798 EXPECT_EQ("Service is already connected to this profile", error.message());
799 }
800
801 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800802 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800803 string profile_name1("profile1");
804 EXPECT_CALL(*profile1, GetRpcIdentifier())
805 .WillRepeatedly(Return(profile_name1));
806 AdoptProfile(manager(), profile1);
807
808 {
809 Error error;
810 EXPECT_CALL(*profile1, AdoptService(_))
811 .WillOnce(Return(true));
812 EXPECT_CALL(*profile0, AbandonService(_))
813 .WillOnce(Return(true));
814 manager()->SetProfileForService(service, profile_name1, &error);
815 EXPECT_TRUE(error.IsSuccess());
816 }
817}
818
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700819TEST_F(ManagerTest, CreateProfile) {
820 // It's much easier to use real Glib here since we want the storage
821 // side-effects.
822 GLib glib;
823 ScopedTempDir temp_dir;
824 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
825
826 Manager manager(control_interface(),
827 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800828 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700829 &glib,
830 run_path(),
831 storage_path(),
832 temp_dir.path().value());
833
834 // Invalid name should be rejected.
835 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
836
Paul Stewartd0a3b812012-03-28 22:48:22 -0700837 // A profile with invalid characters in it should similarly be rejected.
838 EXPECT_EQ(Error::kInvalidArguments,
839 TestCreateProfile(&manager, "valid_profile"));
840
841 // We should be able to create a machine profile.
842 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700843
Gary Morainb672d352012-04-25 09:19:06 -0700844 // We should succeed in creating a valid user profile. Verify the returned
845 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700846 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700847 {
848 Error error;
849 string path;
850 manager.CreateProfile(kProfile, &path, &error);
851 EXPECT_EQ(Error::kSuccess, error.type());
852 EXPECT_EQ("/profile_rpc", path);
853 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700854
855 // We should fail in creating it a second time (already exists).
856 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
857}
858
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700859// We receive PopProfile when a user logs out, and it should always trigger a
860// MemoryLog Clear() call.
861TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
862 GLib glib;
863 ScopedTempDir temp_dir;
864 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
865 Manager manager(control_interface(),
866 dispatcher(),
867 metrics(),
868 &glib,
869 run_path(),
870 storage_path(),
871 temp_dir.path().value());
872 const char kProfile0[] = "~user/profile0";
873 const char kPurgedMessage[] = "This message should be purged";
874 // Create a profile and push it on the stack, leave one uncreated
875 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
876 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
877
878 // Popping a profile which isn't on top should still clear the log.
879 LOG(INFO) << kPurgedMessage;
880 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
881 kPurgedMessage));
882 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
883 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
884 kPurgedMessage));
885
886 // Popping an invalid profile name should do the same thing.
887 LOG(INFO) << kPurgedMessage;
888 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
889 kPurgedMessage));
890 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
891 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
892 kPurgedMessage));
893
894 // Successful pops also purge the message log.
895 LOG(INFO) << kPurgedMessage;
896 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
897 kPurgedMessage));
898 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
899 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
900 kPurgedMessage));
901}
902
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700903TEST_F(ManagerTest, PushPopProfile) {
904 // It's much easier to use real Glib in creating a Manager for this
905 // test here since we want the storage side-effects.
906 GLib glib;
907 ScopedTempDir temp_dir;
908 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
909 Manager manager(control_interface(),
910 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800911 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700912 &glib,
913 run_path(),
914 storage_path(),
915 temp_dir.path().value());
916
917 // Pushing an invalid profile should fail.
918 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
919
Paul Stewartd0a3b812012-03-28 22:48:22 -0700920 // Pushing a default profile that does not exist should fail.
921 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700922
923 const char kProfile0[] = "~user/profile0";
924 const char kProfile1[] = "~user/profile1";
925
926 // Create a couple of profiles.
927 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
928 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
929
930 // Push these profiles on the stack.
931 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
932 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
933
934 // Pushing a profile a second time should fail.
935 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
936 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
937
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800938 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700939 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800940 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700941
942 // Make sure a profile name that doesn't exist fails.
943 const char kProfile2Id[] = "profile2";
944 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
945 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
946
947 // Create a new service, with a specific storage name.
948 scoped_refptr<MockService> service(
949 new NiceMock<MockService>(control_interface(),
950 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800951 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700952 &manager));
953 const char kServiceName[] = "service_storage_name";
954 EXPECT_CALL(*service.get(), GetStorageIdentifier())
955 .WillRepeatedly(Return(kServiceName));
956 EXPECT_CALL(*service.get(), Load(_))
957 .WillRepeatedly(Return(true));
958
959 // Add this service to the manager -- it should end up in the ephemeral
960 // profile.
961 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800962 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700963
964 // Create storage for a profile that contains the service storage name.
965 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
966 kServiceName));
967
968 // When we push the profile, the service should move away from the
969 // ephemeral profile to this new profile since it has an entry for
970 // this service.
971 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800972 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700973 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
974
975 // Insert another profile that should supersede ownership of the service.
976 const char kProfile3Id[] = "profile3";
977 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
978 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
979 kServiceName));
980 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
981 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
982
983 // Popping an invalid profile name should fail.
984 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
985
986 // Popping an profile that is not at the top of the stack should fail.
987 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
988
989 // Popping the top profile should succeed.
990 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
991
992 // Moreover the service should have switched profiles to profile 2.
993 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
994
995 // Popping the top profile should succeed.
996 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
997
998 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800999 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001000
1001 // Pop the remaining two services off the stack.
1002 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1003 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1004
1005 // Next pop should fail with "stack is empty".
1006 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -07001007
1008 const char kMachineProfile0[] = "machineprofile0";
1009 const char kMachineProfile1[] = "machineprofile1";
1010 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
1011 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
1012
1013 // Should be able to push a machine profile.
1014 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
1015
1016 // Should be able to push a user profile atop a machine profile.
1017 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1018
1019 // Pushing a system-wide profile on top of a user profile should fail.
1020 EXPECT_EQ(Error::kInvalidArguments,
1021 TestPushProfile(&manager, kMachineProfile1));
1022
1023 // However if we pop the user profile, we should be able stack another
1024 // machine profile on.
1025 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1026 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001027
1028 // Add two user profiles to the top of the stack.
1029 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1030 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
1031 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
1032 EXPECT_EQ(4, profiles.size());
1033
1034 // PopAllUserProfiles should remove both user profiles, leaving the two
1035 // machine profiles.
1036 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1037 EXPECT_EQ(2, profiles.size());
1038 EXPECT_TRUE(profiles[0]->GetUser().empty());
1039 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001040
1041 // Use InsertUserProfile() instead. Although a machine profile is valid
1042 // in this state, it cannot be added via InsertUserProfile.
1043 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1044 EXPECT_EQ(Error::kInvalidArguments,
1045 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1046 const char kUserHash0[] = "userhash0";
1047 const char kUserHash1[] = "userhash1";
1048 EXPECT_EQ(Error::kSuccess,
1049 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1050 EXPECT_EQ(Error::kSuccess,
1051 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1052 EXPECT_EQ(3, profiles.size());
1053 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1054 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001055}
1056
Paul Stewarte73d05c2012-03-29 16:26:05 -07001057TEST_F(ManagerTest, RemoveProfile) {
1058 // It's much easier to use real Glib in creating a Manager for this
1059 // test here since we want the storage side-effects.
1060 GLib glib;
1061 ScopedTempDir temp_dir;
1062 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1063 Manager manager(control_interface(),
1064 dispatcher(),
1065 metrics(),
1066 &glib,
1067 run_path(),
1068 storage_path(),
1069 temp_dir.path().value());
1070
1071 const char kProfile0[] = "profile0";
1072 FilePath profile_path(
1073 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1074
1075 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1076 ASSERT_TRUE(file_util::PathExists(profile_path));
1077
1078 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1079
1080 // Remove should fail since the profile is still on the stack.
1081 {
1082 Error error;
1083 manager.RemoveProfile(kProfile0, &error);
1084 EXPECT_EQ(Error::kInvalidArguments, error.type());
1085 }
1086
1087 // Profile path should still exist.
1088 EXPECT_TRUE(file_util::PathExists(profile_path));
1089
1090 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1091
1092 // This should succeed now that the profile is off the stack.
1093 {
1094 Error error;
1095 manager.RemoveProfile(kProfile0, &error);
1096 EXPECT_EQ(Error::kSuccess, error.type());
1097 }
1098
1099 // Profile path should no longer exist.
1100 EXPECT_FALSE(file_util::PathExists(profile_path));
1101
1102 // Another remove succeeds, due to a foible in file_util::Delete --
1103 // it is not an error to delete a file that does not exist.
1104 {
1105 Error error;
1106 manager.RemoveProfile(kProfile0, &error);
1107 EXPECT_EQ(Error::kSuccess, error.type());
1108 }
1109
1110 // Let's create an error case that will "work". Create a non-empty
1111 // directory in the place of the profile pathname.
1112 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1113 {
1114 Error error;
1115 manager.RemoveProfile(kProfile0, &error);
1116 EXPECT_EQ(Error::kOperationFailed, error.type());
1117 }
1118}
1119
Paul Stewartd3d03882013-08-29 15:43:42 -07001120TEST_F(ManagerTest, RemoveService) {
1121 MockServiceRefPtr mock_service(
1122 new NiceMock<MockService>(control_interface(),
1123 dispatcher(),
1124 metrics(),
1125 manager()));
1126
1127 // Used in expectations which cannot accept a mock refptr.
1128 const ServiceRefPtr &service = mock_service;
1129
1130 manager()->RegisterService(service);
1131 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1132
1133 scoped_refptr<MockProfile> profile(
1134 new StrictMock<MockProfile>(
1135 control_interface(), metrics(), manager(), ""));
1136 AdoptProfile(manager(), profile);
1137
1138 // If service is ephemeral, it should be unloaded and left ephemeral.
1139 EXPECT_CALL(*profile, AbandonService(service)).Times(0);
1140 EXPECT_CALL(*profile, ConfigureService(service)).Times(0);
1141 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(false));
1142 manager()->RemoveService(service);
1143 Mock::VerifyAndClearExpectations(mock_service);
1144 Mock::VerifyAndClearExpectations(profile);
1145 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1146 EXPECT_TRUE(manager()->HasService(service)); // Since Unload() was false.
1147
1148 // If service is not ephemeral and the Manager finds a profile to assign
1149 // the service to, the service should be re-parented. Note that since we
1150 // are using a MockProfile, ConfigureService() never actually changes the
1151 // Service's profile.
1152 service->set_profile(profile);
1153 EXPECT_CALL(*profile, AbandonService(service));
1154 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(true));
1155 EXPECT_CALL(*mock_service, Unload()).Times(0);
1156 manager()->RemoveService(service);
1157 Mock::VerifyAndClearExpectations(mock_service);
1158 Mock::VerifyAndClearExpectations(profile);
1159 EXPECT_TRUE(manager()->HasService(service));
1160 EXPECT_EQ(profile.get(), service->profile().get());
1161
1162 // If service becomes ephemeral since there is no profile to support it,
1163 // it should be unloaded.
1164 EXPECT_CALL(*profile, AbandonService(service));
1165 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(false));
1166 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(true));
1167 manager()->RemoveService(service);
1168 EXPECT_FALSE(manager()->HasService(service));
1169}
1170
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001171TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1172 // It's much easier to use real Glib in creating a Manager for this
1173 // test here since we want the storage side-effects.
1174 GLib glib;
1175 ScopedTempDir temp_dir;
1176 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1177 Manager manager(control_interface(),
1178 dispatcher(),
1179 metrics(),
1180 &glib,
1181 run_path(),
1182 storage_path(),
1183 temp_dir.path().value());
1184
1185 const char kProfile0[] = "profile0";
1186 FilePath profile_path(
1187 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1188
1189 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1190 ASSERT_TRUE(file_util::PathExists(profile_path));
1191 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1192
1193 // Ensure that even if the backing filestore is removed, we still can't
1194 // create a profile twice.
1195 ASSERT_TRUE(file_util::Delete(profile_path, false));
1196 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1197}
1198
Paul Stewart75225512012-01-26 22:51:33 -08001199// Use this matcher instead of passing RefPtrs directly into the arguments
1200// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1201// system teardown.
1202MATCHER_P(IsRefPtrTo, ref_address, "") {
1203 return arg.get() == ref_address;
1204}
1205
1206TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1207 MockServiceRefPtr s_not_in_profile(
1208 new NiceMock<MockService>(control_interface(),
1209 dispatcher(),
1210 metrics(),
1211 manager()));
1212 MockServiceRefPtr s_not_in_group(
1213 new NiceMock<MockService>(control_interface(),
1214 dispatcher(),
1215 metrics(),
1216 manager()));
1217 MockServiceRefPtr s_configure_fail(
1218 new NiceMock<MockService>(control_interface(),
1219 dispatcher(),
1220 metrics(),
1221 manager()));
1222 MockServiceRefPtr s_configure_succeed(
1223 new NiceMock<MockService>(control_interface(),
1224 dispatcher(),
1225 metrics(),
1226 manager()));
1227
1228 string entry_name("entry_name");
1229 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1230 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1231 .WillRepeatedly(Return("not_entry_name"));
1232 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1233 .WillRepeatedly(Return(entry_name));
1234 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1235 .WillRepeatedly(Return(entry_name));
1236
1237 manager()->RegisterService(s_not_in_profile);
1238 manager()->RegisterService(s_not_in_group);
1239 manager()->RegisterService(s_configure_fail);
1240 manager()->RegisterService(s_configure_succeed);
1241
1242 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001243 new StrictMock<MockProfile>(
1244 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001245 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001246 new StrictMock<MockProfile>(
1247 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001248
1249 s_not_in_group->set_profile(profile1);
1250 s_configure_fail->set_profile(profile1);
1251 s_configure_succeed->set_profile(profile1);
1252
1253 AdoptProfile(manager(), profile0);
1254 AdoptProfile(manager(), profile1);
1255
1256 // No services are a member of this profile.
1257 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1258
1259 // No services that are members of this profile have this entry name.
1260 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1261
1262 // Only services that are members of the profile and group will be abandoned.
1263 EXPECT_CALL(*profile1.get(),
1264 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1265 EXPECT_CALL(*profile1.get(),
1266 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1267 EXPECT_CALL(*profile1.get(),
1268 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1269 .WillOnce(Return(true));
1270 EXPECT_CALL(*profile1.get(),
1271 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1272 .WillOnce(Return(true));
1273
1274 // Never allow services to re-join profile1.
1275 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1276 .WillRepeatedly(Return(false));
1277
1278 // Only allow one of the members of the profile and group to successfully
1279 // join profile0.
1280 EXPECT_CALL(*profile0.get(),
1281 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1282 EXPECT_CALL(*profile0.get(),
1283 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1284 EXPECT_CALL(*profile0.get(),
1285 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1286 .WillOnce(Return(false));
1287 EXPECT_CALL(*profile0.get(),
1288 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1289 .WillOnce(Return(true));
1290
1291 // Expect the failed-to-configure service to have Unload() called on it.
1292 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1293 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1294 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1295 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1296
1297 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1298
1299 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1300 EXPECT_EQ(profile1, s_not_in_group->profile());
1301 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1302
1303 // Since we are using a MockProfile, the profile does not actually change,
1304 // since ConfigureService was not actually called on the service.
1305 EXPECT_EQ(profile1, s_configure_succeed->profile());
1306}
1307
Paul Stewart65512e12012-03-26 18:01:08 -07001308TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1309 MockServiceRefPtr s_will_remove0(
1310 new NiceMock<MockService>(control_interface(),
1311 dispatcher(),
1312 metrics(),
1313 manager()));
1314 MockServiceRefPtr s_will_remove1(
1315 new NiceMock<MockService>(control_interface(),
1316 dispatcher(),
1317 metrics(),
1318 manager()));
1319 MockServiceRefPtr s_will_not_remove0(
1320 new NiceMock<MockService>(control_interface(),
1321 dispatcher(),
1322 metrics(),
1323 manager()));
1324 MockServiceRefPtr s_will_not_remove1(
1325 new NiceMock<MockService>(control_interface(),
1326 dispatcher(),
1327 metrics(),
1328 manager()));
1329
1330 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1331 .Times(4); // Once for each registration.
1332
1333 string entry_name("entry_name");
1334 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1335 .WillRepeatedly(Return(entry_name));
1336 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1337 .WillRepeatedly(Return(entry_name));
1338 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1339 .WillRepeatedly(Return(entry_name));
1340 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1341 .WillRepeatedly(Return(entry_name));
1342
1343 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001344 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001345 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001346 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001347 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001348 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001349 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001350 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001351
1352 // One for each service added above.
1353 ASSERT_EQ(4, manager()->services_.size());
1354
1355 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001356 new StrictMock<MockProfile>(
1357 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001358
1359 s_will_remove0->set_profile(profile);
1360 s_will_remove1->set_profile(profile);
1361 s_will_not_remove0->set_profile(profile);
1362 s_will_not_remove1->set_profile(profile);
1363
1364 AdoptProfile(manager(), profile);
1365
1366 // Deny any of the services re-entry to the profile.
1367 EXPECT_CALL(*profile, ConfigureService(_))
1368 .WillRepeatedly(Return(false));
1369
1370 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1371 .WillOnce(Return(true));
1372 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1373 .WillOnce(Return(true));
1374 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1375 .WillOnce(Return(true));
1376 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1377 .WillOnce(Return(true));
1378
1379 EXPECT_CALL(*s_will_remove0, Unload())
1380 .WillOnce(Return(true));
1381 EXPECT_CALL(*s_will_remove1, Unload())
1382 .WillOnce(Return(true));
1383 EXPECT_CALL(*s_will_not_remove0, Unload())
1384 .WillOnce(Return(false));
1385 EXPECT_CALL(*s_will_not_remove1, Unload())
1386 .WillOnce(Return(false));
1387
1388
1389 // This will cause all the profiles to be unloaded.
1390 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1391
1392 // 2 of the 4 services added above should have been unregistered and
1393 // removed, leaving 2.
1394 EXPECT_EQ(2, manager()->services_.size());
1395 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1396 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1397}
1398
1399TEST_F(ManagerTest, PopProfileWithUnload) {
1400 MockServiceRefPtr s_will_remove0(
1401 new NiceMock<MockService>(control_interface(),
1402 dispatcher(),
1403 metrics(),
1404 manager()));
1405 MockServiceRefPtr s_will_remove1(
1406 new NiceMock<MockService>(control_interface(),
1407 dispatcher(),
1408 metrics(),
1409 manager()));
1410 MockServiceRefPtr s_will_not_remove0(
1411 new NiceMock<MockService>(control_interface(),
1412 dispatcher(),
1413 metrics(),
1414 manager()));
1415 MockServiceRefPtr s_will_not_remove1(
1416 new NiceMock<MockService>(control_interface(),
1417 dispatcher(),
1418 metrics(),
1419 manager()));
1420
1421 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1422 .Times(5); // Once for each registration, and one after profile pop.
1423
1424 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001425 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001426 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001427 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001428 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001429 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001430 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001431 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001432
1433 // One for each service added above.
1434 ASSERT_EQ(4, manager()->services_.size());
1435
1436 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001437 new StrictMock<MockProfile>(
1438 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001439 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001440 new StrictMock<MockProfile>(
1441 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001442
1443 s_will_remove0->set_profile(profile1);
1444 s_will_remove1->set_profile(profile1);
1445 s_will_not_remove0->set_profile(profile1);
1446 s_will_not_remove1->set_profile(profile1);
1447
1448 AdoptProfile(manager(), profile0);
1449 AdoptProfile(manager(), profile1);
1450
1451 // Deny any of the services entry to profile0, so they will all be unloaded.
1452 EXPECT_CALL(*profile0, ConfigureService(_))
1453 .WillRepeatedly(Return(false));
1454
1455 EXPECT_CALL(*s_will_remove0, Unload())
1456 .WillOnce(Return(true));
1457 EXPECT_CALL(*s_will_remove1, Unload())
1458 .WillOnce(Return(true));
1459 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001460 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001461 EXPECT_CALL(*s_will_not_remove1, Unload())
1462 .WillOnce(Return(false));
1463
Philipp Neubeck79173602012-11-13 21:10:09 +01001464 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1465 // profile list.
1466 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1467 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1468
Paul Stewart65512e12012-03-26 18:01:08 -07001469 // This will pop profile1, which should cause all our profiles to unload.
1470 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001471 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001472
1473 // 2 of the 4 services added above should have been unregistered and
1474 // removed, leaving 2.
1475 EXPECT_EQ(2, manager()->services_.size());
1476 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1477 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001478
1479 // Expect the unloaded services to lose their profile reference.
1480 EXPECT_FALSE(s_will_remove0->profile());
1481 EXPECT_FALSE(s_will_remove1->profile());
1482
1483 // If we explicitly deregister a service, the effect should be the same
1484 // with respect to the profile reference.
1485 ASSERT_TRUE(s_will_not_remove0->profile());
1486 manager()->DeregisterService(s_will_not_remove0);
1487 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001488}
1489
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001490TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001491 {
1492 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001493 ::DBus::Variant offline_mode;
1494 offline_mode.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001495 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1496 flimflam::kOfflineModeProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001497 offline_mode,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001498 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001499 }
1500 {
1501 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001502 ::DBus::Variant country;
1503 country.writer().append_string("a_country");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001504 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1505 flimflam::kCountryProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001506 country,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001507 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001508 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001509 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001510 {
1511 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001512 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1513 flimflam::kCountryProperty,
1514 PropertyStoreTest::kBoolV,
1515 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001516 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001517 }
1518 {
1519 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001520 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1521 flimflam::kOfflineModeProperty,
1522 PropertyStoreTest::kStringV,
1523 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001524 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001525 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001526 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001527 {
1528 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001529 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001530 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001531 flimflam::kEnabledTechnologiesProperty,
1532 PropertyStoreTest::kStringsV,
1533 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001534 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001535 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001536}
1537
mukesh agrawal32399322011-09-01 10:53:43 -07001538TEST_F(ManagerTest, RequestScan) {
1539 {
1540 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001541 manager()->RegisterDevice(mock_devices_[0].get());
1542 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001543 EXPECT_CALL(*mock_devices_[0], technology())
1544 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001545 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _, _));
Joshua Krollda798622012-06-05 12:30:48 -07001546 EXPECT_CALL(*mock_devices_[1], technology())
1547 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001548 EXPECT_CALL(*mock_devices_[1], Scan(_, _, _)).Times(0);
Wade Guthrie68d41092013-04-02 12:56:02 -07001549 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001550 }
1551
1552 {
1553 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001554 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001555 EXPECT_EQ(Error::kInvalidArguments, error.type());
1556 }
1557}
1558
Darin Petkovb65c2452012-02-23 15:17:06 +01001559TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001560 KeyValueStore args;
1561 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001562 manager()->GetService(args, &e);
1563 EXPECT_EQ(Error::kInvalidArguments, e.type());
1564 EXPECT_EQ("must specify service type", e.message());
1565}
1566
1567TEST_F(ManagerTest, GetServiceUnknownType) {
1568 KeyValueStore args;
1569 Error e;
1570 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1571 manager()->GetService(args, &e);
1572 EXPECT_EQ(Error::kNotSupported, e.type());
1573 EXPECT_EQ("service type is unsupported", e.message());
1574}
1575
Paul Stewart35eff132013-04-12 12:08:40 -07001576TEST_F(ManagerTest, GetServiceEthernetEap) {
1577 KeyValueStore args;
1578 Error e;
Paul Stewart55fc64c2013-07-18 09:51:35 -07001579 ServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1580 dispatcher(),
1581 metrics(),
1582 manager());
Paul Stewart35eff132013-04-12 12:08:40 -07001583 args.SetString(flimflam::kTypeProperty, kTypeEthernetEap);
1584 SetEapProviderService(service);
1585 EXPECT_EQ(service, manager()->GetService(args, &e));
1586 EXPECT_TRUE(e.IsSuccess());
1587}
1588
Darin Petkovb65c2452012-02-23 15:17:06 +01001589TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001590 KeyValueStore args;
1591 Error e;
1592 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001593 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001594 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001595 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001596 manager()->GetService(args, &e);
1597 EXPECT_TRUE(e.IsSuccess());
1598}
1599
Darin Petkov33af05c2012-02-28 10:10:30 +01001600TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1601 KeyValueStore args;
1602 Error e;
1603 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001604 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001605 new StrictMock<MockProfile>(
1606 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001607 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001608 ServiceRefPtr service = manager()->GetService(args, &e);
1609 EXPECT_EQ(Error::kNotSupported, e.type());
1610 EXPECT_FALSE(service);
1611}
1612
Darin Petkovb65c2452012-02-23 15:17:06 +01001613TEST_F(ManagerTest, GetServiceVPN) {
1614 KeyValueStore args;
1615 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001616 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001617 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001618 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001619 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001620 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001621 new StrictMock<MockProfile>(
1622 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001623 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001624
1625#if defined(DISABLE_VPN)
1626
1627 ServiceRefPtr service = manager()->GetService(args, &e);
1628 EXPECT_EQ(Error::kNotSupported, e.type());
1629 EXPECT_FALSE(service);
1630
1631#else
1632
Paul Stewart7f5ad572012-06-04 15:18:54 -07001633 ServiceRefPtr updated_service;
1634 EXPECT_CALL(*profile, UpdateService(_))
1635 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1636 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001637 EXPECT_CALL(*profile, LoadService(_))
1638 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001639 EXPECT_CALL(*profile, ConfigureService(_))
1640 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001641 ServiceRefPtr service = manager()->GetService(args, &e);
1642 EXPECT_TRUE(e.IsSuccess());
1643 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001644 EXPECT_EQ(service, updated_service);
1645 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001646
1647#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001648}
1649
Darin Petkovc63dcf02012-05-24 11:51:43 +02001650TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1651 KeyValueStore args;
1652 Error e;
1653 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1654 ServiceRefPtr service = manager()->GetService(args, &e);
1655 EXPECT_EQ(Error::kInvalidArguments, e.type());
1656 EXPECT_EQ("Missing WiMAX network id.", e.message());
1657 EXPECT_FALSE(service);
1658}
1659
Darin Petkovd1cd7972012-05-22 15:26:15 +02001660TEST_F(ManagerTest, GetServiceWiMax) {
1661 KeyValueStore args;
1662 Error e;
1663 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001664 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1665 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1666 ServiceRefPtr service = manager()->GetService(args, &e);
1667 EXPECT_TRUE(e.IsSuccess());
1668 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001669}
1670
Paul Stewart7f61e522012-03-22 11:13:45 -07001671TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1672 // Manager calls ActiveProfile() so we need at least one profile installed.
1673 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001674 new NiceMock<MockProfile>(
1675 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001676 AdoptProfile(manager(), profile);
1677
1678 KeyValueStore args;
1679 args.SetString(flimflam::kProfileProperty, "xxx");
1680 Error error;
1681 manager()->ConfigureService(args, &error);
1682 EXPECT_EQ(Error::kInvalidArguments, error.type());
1683 EXPECT_EQ("Invalid profile name xxx", error.message());
1684}
1685
1686TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1687 // Manager calls ActiveProfile() so we need at least one profile installed.
1688 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001689 new NiceMock<MockProfile>(
1690 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001691 AdoptProfile(manager(), profile);
1692
1693 KeyValueStore args;
1694 Error error;
1695 manager()->ConfigureService(args, &error);
1696 EXPECT_EQ(Error::kInvalidArguments, error.type());
1697 EXPECT_EQ("must specify service type", error.message());
1698}
1699
1700// A registered service in the ephemeral profile should be moved to the
1701// active profile as a part of configuration if no profile was explicitly
1702// specified.
1703TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1704 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001705 new NiceMock<MockProfile>(
1706 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001707
1708 AdoptProfile(manager(), profile); // This is now the active profile.
1709
Paul Stewartd2e1c362013-03-03 19:06:07 -08001710 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001711 scoped_refptr<MockWiFiService> service(
1712 new NiceMock<MockWiFiService>(control_interface(),
1713 dispatcher(),
1714 metrics(),
1715 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001716 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001717 ssid,
1718 "",
1719 "",
1720 false));
1721
1722 manager()->RegisterService(service);
1723 service->set_profile(GetEphemeralProfile(manager()));
1724
Paul Stewart3c504012013-01-17 17:49:58 -08001725 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001726 .WillOnce(Return(service));
1727 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1728 .WillOnce(Return(true));
1729 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1730 .WillOnce(Return(true));
1731
1732 KeyValueStore args;
1733 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1734 Error error;
1735 manager()->ConfigureService(args, &error);
1736 EXPECT_TRUE(error.IsSuccess());
1737}
1738
Paul Stewart2c575d22012-12-07 12:28:57 -08001739// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001740// specify a profile, it should be moved from the profile it was previously
1741// in to the specified profile if one was requested.
1742TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1743 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001744 new NiceMock<MockProfile>(
1745 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001746 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001747 new NiceMock<MockProfile>(
1748 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001749
1750 const string kProfileName0 = "profile0";
1751 const string kProfileName1 = "profile1";
1752
1753 EXPECT_CALL(*profile0, GetRpcIdentifier())
1754 .WillRepeatedly(Return(kProfileName0));
1755 EXPECT_CALL(*profile1, GetRpcIdentifier())
1756 .WillRepeatedly(Return(kProfileName1));
1757
1758 AdoptProfile(manager(), profile0);
1759 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1760
Paul Stewartd2e1c362013-03-03 19:06:07 -08001761 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001762 scoped_refptr<MockWiFiService> service(
1763 new NiceMock<MockWiFiService>(control_interface(),
1764 dispatcher(),
1765 metrics(),
1766 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001767 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001768 ssid,
1769 "",
1770 "",
1771 false));
1772
1773 manager()->RegisterService(service);
1774 service->set_profile(profile1);
1775
Paul Stewart3c504012013-01-17 17:49:58 -08001776 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001777 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001778 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1779 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001780 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1781 .WillOnce(Return(true));
1782 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1783 .WillOnce(Return(true));
1784 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1785 .WillOnce(Return(true));
1786
1787 KeyValueStore args;
1788 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1789 args.SetString(flimflam::kProfileProperty, kProfileName0);
1790 Error error;
1791 manager()->ConfigureService(args, &error);
1792 EXPECT_TRUE(error.IsSuccess());
1793 service->set_profile(NULL); // Breaks refcounting loop.
1794}
1795
Paul Stewart2c575d22012-12-07 12:28:57 -08001796// If we configure a service that is already a member of the specified
1797// profile, the Manager should not call LoadService or AdoptService again
1798// on this service.
1799TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1800 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001801 new NiceMock<MockProfile>(
1802 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001803
1804 const string kProfileName0 = "profile0";
1805
1806 EXPECT_CALL(*profile0, GetRpcIdentifier())
1807 .WillRepeatedly(Return(kProfileName0));
1808
1809 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1810
Paul Stewartd2e1c362013-03-03 19:06:07 -08001811 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001812 scoped_refptr<MockWiFiService> service(
1813 new NiceMock<MockWiFiService>(control_interface(),
1814 dispatcher(),
1815 metrics(),
1816 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001817 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001818 ssid,
1819 "",
1820 "",
1821 false));
1822
1823 manager()->RegisterService(service);
1824 service->set_profile(profile0);
1825
Paul Stewart3c504012013-01-17 17:49:58 -08001826 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001827 .WillOnce(Return(service));
1828 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1829 .Times(0);
1830 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1831 .WillOnce(Return(true));
1832 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1833 .Times(0);
1834
1835 KeyValueStore args;
1836 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1837 args.SetString(flimflam::kProfileProperty, kProfileName0);
1838 Error error;
1839 manager()->ConfigureService(args, &error);
1840 EXPECT_TRUE(error.IsSuccess());
1841 service->set_profile(NULL); // Breaks refcounting loop.
1842}
1843
Paul Stewart7f61e522012-03-22 11:13:45 -07001844// An unregistered service should remain unregistered, but its contents should
1845// be saved to the specified profile nonetheless.
1846TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1847 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001848 new NiceMock<MockProfile>(
1849 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001850 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001851 new NiceMock<MockProfile>(
1852 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001853
1854 const string kProfileName0 = "profile0";
1855 const string kProfileName1 = "profile1";
1856
1857 EXPECT_CALL(*profile0, GetRpcIdentifier())
1858 .WillRepeatedly(Return(kProfileName0));
1859 EXPECT_CALL(*profile1, GetRpcIdentifier())
1860 .WillRepeatedly(Return(kProfileName1));
1861
1862 AdoptProfile(manager(), profile0);
1863 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1864
Paul Stewartd2e1c362013-03-03 19:06:07 -08001865 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001866 scoped_refptr<MockWiFiService> service(
1867 new NiceMock<MockWiFiService>(control_interface(),
1868 dispatcher(),
1869 metrics(),
1870 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001871 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001872 ssid,
1873 "",
1874 "",
1875 false));
1876
1877 service->set_profile(profile1);
1878
Paul Stewart3c504012013-01-17 17:49:58 -08001879 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001880 .WillOnce(Return(service));
1881 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1882 .WillOnce(Return(true));
1883 EXPECT_CALL(*profile0, AdoptService(_))
1884 .Times(0);
1885 EXPECT_CALL(*profile1, AdoptService(_))
1886 .Times(0);
1887
1888 KeyValueStore args;
1889 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1890 args.SetString(flimflam::kProfileProperty, kProfileName0);
1891 Error error;
1892 manager()->ConfigureService(args, &error);
1893 EXPECT_TRUE(error.IsSuccess());
1894}
1895
Paul Stewartd2e1c362013-03-03 19:06:07 -08001896TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1897 KeyValueStore args;
1898 Error error;
1899 ServiceRefPtr service =
1900 manager()->ConfigureServiceForProfile("", args, &error);
Paul Stewart6ae05892013-07-29 12:21:12 -07001901 EXPECT_EQ(Error::kInvalidArguments, error.type());
1902 EXPECT_EQ("must specify service type", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001903 EXPECT_EQ(NULL, service.get());
1904}
1905
1906TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1907 KeyValueStore args;
1908 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1909 Error error;
1910 ServiceRefPtr service =
1911 manager()->ConfigureServiceForProfile("", args, &error);
1912 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07001913 EXPECT_EQ("service type is unsupported", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001914 EXPECT_EQ(NULL, service.get());
1915}
1916
1917TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1918 KeyValueStore args;
1919 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1920 Error error;
1921 ServiceRefPtr service =
1922 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1923 EXPECT_EQ(Error::kNotFound, error.type());
1924 EXPECT_EQ("Profile specified was not found", error.message());
1925 EXPECT_EQ(NULL, service.get());
1926}
1927
1928TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1929 const string kProfileName0 = "profile0";
1930 const string kProfileName1 = "profile1";
1931 scoped_refptr<MockProfile> profile0(
1932 AddNamedMockProfileToManager(manager(), kProfileName0));
1933
1934 KeyValueStore args;
1935 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1936 args.SetString(flimflam::kProfileProperty, kProfileName1);
1937 Error error;
1938 ServiceRefPtr service =
1939 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1940 EXPECT_EQ(Error::kInvalidArguments, error.type());
1941 EXPECT_EQ("Profile argument does not match that in "
1942 "the configuration arguments", error.message());
1943 EXPECT_EQ(NULL, service.get());
1944}
1945
1946TEST_F(ManagerTest,
1947 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1948 const string kProfileName0 = "profile0";
1949 scoped_refptr<MockProfile> profile0(
1950 AddNamedMockProfileToManager(manager(), kProfileName0));
1951 KeyValueStore args;
1952 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1953 args.SetString(flimflam::kProfileProperty, kProfileName0);
1954
1955 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1956 .WillOnce(Return(WiFiServiceRefPtr()));
1957 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1958 .WillOnce(Return(WiFiServiceRefPtr()));
1959 Error error;
1960 ServiceRefPtr service =
1961 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1962 // Since we didn't set the error in the GetService expectation above...
1963 EXPECT_TRUE(error.IsSuccess());
1964 EXPECT_EQ(NULL, service.get());
1965}
1966
1967TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1968 const string kProfileName0 = "profile0";
1969 scoped_refptr<MockProfile> profile0(
1970 AddNamedMockProfileToManager(manager(), kProfileName0));
1971
1972 KeyValueStore args;
1973 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1974
1975 scoped_refptr<MockWiFiService> mock_service(
1976 new NiceMock<MockWiFiService>(control_interface(),
1977 dispatcher(),
1978 metrics(),
1979 manager(),
1980 wifi_provider_,
1981 vector<uint8_t>(),
1982 flimflam::kModeManaged,
1983 flimflam::kSecurityNone,
1984 false));
1985 ServiceRefPtr mock_service_generic(mock_service.get());
1986 mock_service->set_profile(profile0);
1987 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1988 .WillOnce(Return(WiFiServiceRefPtr()));
1989 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1990 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1991 .WillOnce(Return(true));
1992 Error error;
1993 ServiceRefPtr service =
1994 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1995 EXPECT_TRUE(error.IsSuccess());
1996 EXPECT_EQ(mock_service.get(), service.get());
1997 mock_service->set_profile(NULL); // Breaks reference cycle.
1998}
1999
2000TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
2001 scoped_refptr<MockService> mock_service(
2002 new NiceMock<MockService>(control_interface(),
2003 dispatcher(),
2004 metrics(),
2005 manager()));
2006 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002007 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002008 manager()->RegisterService(mock_service);
2009 ServiceRefPtr mock_service_generic(mock_service.get());
2010
2011 const string kProfileName = "profile";
2012 scoped_refptr<MockProfile> profile(
2013 AddNamedMockProfileToManager(manager(), kProfileName));
2014 mock_service->set_profile(profile);
2015
2016 EXPECT_CALL(*mock_service, technology())
2017 .WillOnce(Return(Technology::kCellular))
2018 .WillOnce(Return(Technology::kWifi));
2019
2020 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
2021 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2022 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2023
2024 KeyValueStore args;
2025 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2026 args.SetString(flimflam::kGuidProperty, kGUID);
2027
2028 // The first attempt should fail because the service reports a technology
2029 // other than "WiFi".
2030 {
2031 Error error;
2032 ServiceRefPtr service =
2033 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2034 EXPECT_EQ(NULL, service.get());
2035 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07002036 EXPECT_EQ("This GUID matches a non-wifi service", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08002037 }
2038
2039 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2040 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2041
2042 {
2043 Error error;
2044 ServiceRefPtr service =
2045 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2046 EXPECT_TRUE(error.IsSuccess());
2047 EXPECT_EQ(mock_service.get(), service.get());
2048 EXPECT_EQ(profile.get(), service->profile().get());
2049 }
2050 mock_service->set_profile(NULL); // Breaks reference cycle.
2051}
2052
2053TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
2054 const string kProfileName = "profile";
2055 scoped_refptr<MockProfile> profile(
2056 AddNamedMockProfileToManager(manager(), kProfileName));
2057
2058 scoped_refptr<MockWiFiService> mock_service(
2059 new NiceMock<MockWiFiService>(control_interface(),
2060 dispatcher(),
2061 metrics(),
2062 manager(),
2063 wifi_provider_,
2064 vector<uint8_t>(),
2065 flimflam::kModeManaged,
2066 flimflam::kSecurityNone,
2067 false));
2068 mock_service->set_profile(profile);
2069 ServiceRefPtr mock_service_generic(mock_service.get());
2070
2071 KeyValueStore args;
2072 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2073 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2074 .WillOnce(Return(mock_service));
2075 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2076 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2077 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2078 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2079
2080 Error error;
2081 ServiceRefPtr service =
2082 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2083 EXPECT_TRUE(error.IsSuccess());
2084 EXPECT_EQ(mock_service.get(), service.get());
2085 EXPECT_EQ(profile.get(), service->profile().get());
2086 mock_service->set_profile(NULL); // Breaks reference cycle.
2087}
2088
2089TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2090 const string kProfileName = "profile";
2091 scoped_refptr<MockProfile> profile(
2092 AddNamedMockProfileToManager(manager(), kProfileName));
2093
2094 scoped_refptr<MockWiFiService> mock_service(
2095 new NiceMock<MockWiFiService>(control_interface(),
2096 dispatcher(),
2097 metrics(),
2098 manager(),
2099 wifi_provider_,
2100 vector<uint8_t>(),
2101 flimflam::kModeManaged,
2102 flimflam::kSecurityNone,
2103 false));
2104 mock_service->set_profile(GetEphemeralProfile(manager()));
2105 ServiceRefPtr mock_service_generic(mock_service.get());
2106
2107 KeyValueStore args;
2108 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2109 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2110 .WillOnce(Return(mock_service));
2111 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2112 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2113 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2114
2115 Error error;
2116 ServiceRefPtr service =
2117 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2118 EXPECT_TRUE(error.IsSuccess());
2119 EXPECT_EQ(mock_service.get(), service.get());
2120 EXPECT_EQ(profile.get(), service->profile().get());
2121 mock_service->set_profile(NULL); // Breaks reference cycle.
2122}
2123
2124TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2125 const string kProfileName0 = "profile0";
2126 scoped_refptr<MockProfile> profile0(
2127 AddNamedMockProfileToManager(manager(), kProfileName0));
2128 const string kProfileName1 = "profile1";
2129 scoped_refptr<MockProfile> profile1(
2130 AddNamedMockProfileToManager(manager(), kProfileName1));
2131
2132 scoped_refptr<MockWiFiService> mock_service(
2133 new NiceMock<MockWiFiService>(control_interface(),
2134 dispatcher(),
2135 metrics(),
2136 manager(),
2137 wifi_provider_,
2138 vector<uint8_t>(),
2139 flimflam::kModeManaged,
2140 flimflam::kSecurityNone,
2141 false));
2142 manager()->RegisterService(mock_service);
2143 mock_service->set_profile(profile0);
2144 ServiceRefPtr mock_service_generic(mock_service.get());
2145
2146 KeyValueStore args;
2147 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2148 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2149 .WillOnce(Return(mock_service));
2150 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2151 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2152 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2153 // This happens once to make the service loadable for the ConfigureService
2154 // below, and a second time after the service is modified.
2155 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2156 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2157 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2158 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2159
2160 Error error;
2161 ServiceRefPtr service =
2162 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2163 EXPECT_TRUE(error.IsSuccess());
2164 EXPECT_EQ(mock_service.get(), service.get());
2165 mock_service->set_profile(NULL); // Breaks reference cycle.
2166}
2167
2168TEST_F(ManagerTest,
2169 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2170 const string kProfileName0 = "profile0";
2171 scoped_refptr<MockProfile> profile0(
2172 AddNamedMockProfileToManager(manager(), kProfileName0));
2173 const string kProfileName1 = "profile1";
2174 scoped_refptr<MockProfile> profile1(
2175 AddNamedMockProfileToManager(manager(), kProfileName1));
2176
2177 scoped_refptr<MockWiFiService> matching_service(
2178 new StrictMock<MockWiFiService>(control_interface(),
2179 dispatcher(),
2180 metrics(),
2181 manager(),
2182 wifi_provider_,
2183 vector<uint8_t>(),
2184 flimflam::kModeManaged,
2185 flimflam::kSecurityNone,
2186 false));
2187 matching_service->set_profile(profile1);
2188
2189 // We need to get rid of our reference to this mock service as soon
2190 // as Manager::ConfigureServiceForProfile() takes a reference in its
2191 // call to WiFiProvider::CreateTemporaryService(). This way the
2192 // latter function can keep a DCHECK(service->HasOneRef() even in
2193 // unit tests.
2194 temp_mock_service_ =
2195 new NiceMock<MockWiFiService>(control_interface(),
2196 dispatcher(),
2197 metrics(),
2198 manager(),
2199 wifi_provider_,
2200 vector<uint8_t>(),
2201 flimflam::kModeManaged,
2202 flimflam::kSecurityNone,
2203 false);
2204
2205 // Only hold a pointer here so we don't affect the refcount.
2206 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2207
2208 KeyValueStore args;
2209 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2210 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2211 .WillOnce(Return(matching_service));
2212 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2213 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2214 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2215 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2216 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2217 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2218 .Times(1);
2219 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2220 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2221
2222 Error error;
2223 ServiceRefPtr service =
2224 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2225 EXPECT_TRUE(error.IsSuccess());
2226 EXPECT_EQ(NULL, service.get());
2227 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2228}
2229
Paul Stewart7a20aa42013-01-17 12:21:41 -08002230TEST_F(ManagerTest, FindMatchingService) {
2231 KeyValueStore args;
2232 {
2233 Error error;
2234 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2235 EXPECT_EQ(Error::kNotFound, error.type());
2236 }
2237
2238 scoped_refptr<MockService> mock_service0(
2239 new NiceMock<MockService>(control_interface(),
2240 dispatcher(),
2241 metrics(),
2242 manager()));
2243 scoped_refptr<MockService> mock_service1(
2244 new NiceMock<MockService>(control_interface(),
2245 dispatcher(),
2246 metrics(),
2247 manager()));
2248 manager()->RegisterService(mock_service0);
2249 manager()->RegisterService(mock_service1);
2250 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2251 .WillOnce(Return(true))
2252 .WillRepeatedly(Return(false));
2253 {
2254 Error error;
2255 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2256 EXPECT_TRUE(error.IsSuccess());
2257 }
2258 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2259 .WillOnce(Return(true))
2260 .WillRepeatedly(Return(false));
2261 {
2262 Error error;
2263 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2264 EXPECT_TRUE(error.IsSuccess());
2265 }
2266 {
2267 Error error;
2268 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2269 EXPECT_EQ(Error::kNotFound, error.type());
2270 }
2271}
2272
Paul Stewart22aa71b2011-09-16 12:15:11 -07002273TEST_F(ManagerTest, TechnologyOrder) {
2274 Error error;
2275 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2276 string(flimflam::kTypeWifi), &error);
2277 ASSERT_TRUE(error.IsSuccess());
2278 EXPECT_EQ(manager()->GetTechnologyOrder(),
2279 string(flimflam::kTypeEthernet) + "," +
2280 string(flimflam::kTypeWifi));
2281
2282 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2283 string(flimflam::kTypeWifi), &error);
2284 ASSERT_FALSE(error.IsSuccess());
2285 EXPECT_EQ(Error::kInvalidArguments, error.type());
2286 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2287 string(flimflam::kTypeWifi),
2288 manager()->GetTechnologyOrder());
2289}
2290
2291TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002292 // TODO(quiche): Some of these tests would probably fit better in
2293 // service_unittest, since the actual comparison of Services is
Paul Stewartee6b3d72013-07-12 16:07:51 -07002294 // implemented in Service. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002295
Paul Stewart22aa71b2011-09-16 12:15:11 -07002296 scoped_refptr<MockService> mock_service0(
2297 new NiceMock<MockService>(control_interface(),
2298 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002299 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002300 manager()));
2301 scoped_refptr<MockService> mock_service1(
2302 new NiceMock<MockService>(control_interface(),
2303 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002304 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002305 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002306
2307 manager()->RegisterService(mock_service0);
2308 manager()->RegisterService(mock_service1);
2309
Darin Petkov457728b2013-01-09 09:49:08 +01002310 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002311 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2312
2313 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002314 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002315 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2316
2317 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002318 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002319 manager()->UpdateService(mock_service1);
2320 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2321
2322 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002323 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002324 manager()->UpdateService(mock_service0);
2325 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2326
2327 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002328 EXPECT_CALL(*mock_service0.get(), technology())
2329 .WillRepeatedly(Return((Technology::kWifi)));
2330 EXPECT_CALL(*mock_service1.get(), technology())
2331 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002332
2333 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002334 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002335 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002336 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2337
2338 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2339 string(flimflam::kTypeEthernet), &error);
2340 EXPECT_TRUE(error.IsSuccess());
2341 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2342
Gaurav Shah435de2c2011-11-17 19:01:07 -08002343 // Priority.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002344 mock_service0->SetPriority(1, NULL);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002345 manager()->UpdateService(mock_service0);
2346 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2347
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002348 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002349 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002350 manager()->UpdateService(mock_service1);
2351 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2352
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002353 // Auto-connect.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002354 mock_service0->SetAutoConnect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002355 manager()->UpdateService(mock_service0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002356 mock_service1->SetAutoConnect(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002357 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002358 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2359
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002360 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2361 // to any of the others below, so we reset to the default state after
2362 // testing.
2363 EXPECT_CALL(*mock_service1.get(),
2364 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2365 .WillOnce(Return(true))
2366 .WillRepeatedly(Return(false));
2367 manager()->UpdateService(mock_service1);
2368 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2369 manager()->UpdateService(mock_service0);
2370 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2371
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002372 // Connectable.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002373 mock_service1->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002374 manager()->UpdateService(mock_service1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002375 mock_service0->SetConnectable(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002376 manager()->UpdateService(mock_service0);
2377 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2378
2379 // IsFailed.
2380 EXPECT_CALL(*mock_service0.get(), state())
2381 .WillRepeatedly(Return(Service::kStateIdle));
2382 EXPECT_CALL(*mock_service0.get(), IsFailed())
2383 .WillRepeatedly(Return(false));
2384 manager()->UpdateService(mock_service0);
2385 EXPECT_CALL(*mock_service0.get(), state())
2386 .WillRepeatedly(Return(Service::kStateFailure));
2387 EXPECT_CALL(*mock_service1.get(), IsFailed())
2388 .WillRepeatedly(Return(true));
2389 manager()->UpdateService(mock_service1);
2390 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2391
2392 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002393 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002394 .WillRepeatedly(Return(Service::kStateAssociating));
2395 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002396 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002397 manager()->UpdateService(mock_service1);
2398 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2399
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002400 // Connected.
2401 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002402 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002403 EXPECT_CALL(*mock_service0.get(), IsConnected())
2404 .WillRepeatedly(Return(true));
2405 manager()->UpdateService(mock_service0);
2406 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2407
Paul Stewarta121c442012-06-09 14:12:58 -07002408 // Portal.
2409 EXPECT_CALL(*mock_service1.get(), state())
2410 .WillRepeatedly(Return(Service::kStateConnected));
2411 EXPECT_CALL(*mock_service1.get(), IsConnected())
2412 .WillRepeatedly(Return(true));
2413 manager()->UpdateService(mock_service1);
2414 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2415
Paul Stewart22aa71b2011-09-16 12:15:11 -07002416 manager()->DeregisterService(mock_service0);
2417 manager()->DeregisterService(mock_service1);
2418}
2419
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002420TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002421 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002422 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002423
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002424 scoped_refptr<MockService> mock_service0(
2425 new NiceMock<MockService>(control_interface(),
2426 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002427 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002428 manager()));
2429 scoped_refptr<MockService> mock_service1(
2430 new NiceMock<MockService>(control_interface(),
2431 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002432 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002433 manager()));
2434
2435 scoped_refptr<MockConnection> mock_connection0(
2436 new NiceMock<MockConnection>(device_info_.get()));
2437 scoped_refptr<MockConnection> mock_connection1(
2438 new NiceMock<MockConnection>(device_info_.get()));
2439
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002440 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002441 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002442 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002443 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002444 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002445 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002446
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002447 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002448 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002449
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002450 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002451 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002452 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002453
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002454 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002455 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002456 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002457
Paul Stewartce4ec192012-03-14 12:53:46 -07002458 mock_service0->set_mock_connection(mock_connection0);
2459 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002460
2461 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002462 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002463 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002464
Darin Petkova5e07ef2012-07-09 14:27:57 +02002465 ServiceWatcher service_watcher;
2466 int tag =
2467 manager()->RegisterDefaultServiceCallback(
2468 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2469 service_watcher.AsWeakPtr()));
2470 EXPECT_EQ(1, tag);
2471
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002472 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002473 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2474 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002475 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002476 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002477 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002478
Darin Petkova5e07ef2012-07-09 14:27:57 +02002479 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002480 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002481 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002482 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002483 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002484 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002485 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002486
Paul Stewartce4ec192012-03-14 12:53:46 -07002487 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002488 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002489 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002490 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002491
2492 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002493 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002494}
2495
Darin Petkova5e07ef2012-07-09 14:27:57 +02002496TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2497 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2498 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2499
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002500 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002501 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002502
2503 scoped_refptr<MockService> mock_service(
2504 new NiceMock<MockService>(
2505 control_interface(), dispatcher(), metrics(), manager()));
2506 ServiceRefPtr service = mock_service;
2507 ServiceRefPtr null_service;
2508
2509 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2510 manager()->NotifyDefaultServiceChanged(null_service);
2511
2512 ServiceWatcher service_watcher1;
2513 ServiceWatcher service_watcher2;
2514 int tag1 =
2515 manager()->RegisterDefaultServiceCallback(
2516 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2517 service_watcher1.AsWeakPtr()));
2518 EXPECT_EQ(1, tag1);
2519 int tag2 =
2520 manager()->RegisterDefaultServiceCallback(
2521 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2522 service_watcher2.AsWeakPtr()));
2523 EXPECT_EQ(2, tag2);
2524
2525 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2526 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2527 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2528 manager()->NotifyDefaultServiceChanged(null_service);
2529
2530 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2531 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2532 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2533 manager()->NotifyDefaultServiceChanged(mock_service);
2534
2535 manager()->DeregisterDefaultServiceCallback(tag1);
2536 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2537 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2538 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2539 manager()->NotifyDefaultServiceChanged(mock_service);
2540 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2541
2542 manager()->DeregisterDefaultServiceCallback(tag2);
2543 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2544 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2545 manager()->NotifyDefaultServiceChanged(mock_service);
2546
2547 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2548 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2549}
2550
Gaurav Shah435de2c2011-11-17 19:01:07 -08002551TEST_F(ManagerTest, AvailableTechnologies) {
2552 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2553 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002554 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002555 manager(),
2556 "null4",
2557 "addr4",
2558 0));
2559 manager()->RegisterDevice(mock_devices_[0]);
2560 manager()->RegisterDevice(mock_devices_[1]);
2561 manager()->RegisterDevice(mock_devices_[2]);
2562 manager()->RegisterDevice(mock_devices_[3]);
2563
2564 ON_CALL(*mock_devices_[0].get(), technology())
2565 .WillByDefault(Return(Technology::kEthernet));
2566 ON_CALL(*mock_devices_[1].get(), technology())
2567 .WillByDefault(Return(Technology::kWifi));
2568 ON_CALL(*mock_devices_[2].get(), technology())
2569 .WillByDefault(Return(Technology::kCellular));
2570 ON_CALL(*mock_devices_[3].get(), technology())
2571 .WillByDefault(Return(Technology::kWifi));
2572
2573 set<string> expected_technologies;
2574 expected_technologies.insert(Technology::NameFromIdentifier(
2575 Technology::kEthernet));
2576 expected_technologies.insert(Technology::NameFromIdentifier(
2577 Technology::kWifi));
2578 expected_technologies.insert(Technology::NameFromIdentifier(
2579 Technology::kCellular));
2580 Error error;
2581 vector<string> technologies = manager()->AvailableTechnologies(&error);
2582
2583 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2584 ContainerEq(expected_technologies));
2585}
2586
2587TEST_F(ManagerTest, ConnectedTechnologies) {
2588 scoped_refptr<MockService> connected_service1(
2589 new NiceMock<MockService>(control_interface(),
2590 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002591 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002592 manager()));
2593 scoped_refptr<MockService> connected_service2(
2594 new NiceMock<MockService>(control_interface(),
2595 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002596 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002597 manager()));
2598 scoped_refptr<MockService> disconnected_service1(
2599 new NiceMock<MockService>(control_interface(),
2600 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002601 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002602 manager()));
2603 scoped_refptr<MockService> disconnected_service2(
2604 new NiceMock<MockService>(control_interface(),
2605 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002606 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002607 manager()));
2608
2609 ON_CALL(*connected_service1.get(), IsConnected())
2610 .WillByDefault(Return(true));
2611 ON_CALL(*connected_service2.get(), IsConnected())
2612 .WillByDefault(Return(true));
2613
2614 manager()->RegisterService(connected_service1);
2615 manager()->RegisterService(connected_service2);
2616 manager()->RegisterService(disconnected_service1);
2617 manager()->RegisterService(disconnected_service2);
2618
2619 manager()->RegisterDevice(mock_devices_[0]);
2620 manager()->RegisterDevice(mock_devices_[1]);
2621 manager()->RegisterDevice(mock_devices_[2]);
2622 manager()->RegisterDevice(mock_devices_[3]);
2623
2624 ON_CALL(*mock_devices_[0].get(), technology())
2625 .WillByDefault(Return(Technology::kEthernet));
2626 ON_CALL(*mock_devices_[1].get(), technology())
2627 .WillByDefault(Return(Technology::kWifi));
2628 ON_CALL(*mock_devices_[2].get(), technology())
2629 .WillByDefault(Return(Technology::kCellular));
2630 ON_CALL(*mock_devices_[3].get(), technology())
2631 .WillByDefault(Return(Technology::kWifi));
2632
2633 mock_devices_[0]->SelectService(connected_service1);
2634 mock_devices_[1]->SelectService(disconnected_service1);
2635 mock_devices_[2]->SelectService(disconnected_service2);
2636 mock_devices_[3]->SelectService(connected_service2);
2637
2638 set<string> expected_technologies;
2639 expected_technologies.insert(Technology::NameFromIdentifier(
2640 Technology::kEthernet));
2641 expected_technologies.insert(Technology::NameFromIdentifier(
2642 Technology::kWifi));
2643 Error error;
2644
2645 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2646 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2647 ContainerEq(expected_technologies));
2648}
2649
2650TEST_F(ManagerTest, DefaultTechnology) {
2651 scoped_refptr<MockService> connected_service(
2652 new NiceMock<MockService>(control_interface(),
2653 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002654 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002655 manager()));
2656 scoped_refptr<MockService> disconnected_service(
2657 new NiceMock<MockService>(control_interface(),
2658 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002659 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002660 manager()));
2661
2662 // Connected. WiFi.
2663 ON_CALL(*connected_service.get(), IsConnected())
2664 .WillByDefault(Return(true));
2665 ON_CALL(*connected_service.get(), state())
2666 .WillByDefault(Return(Service::kStateConnected));
2667 ON_CALL(*connected_service.get(), technology())
2668 .WillByDefault(Return(Technology::kWifi));
2669
2670 // Disconnected. Ethernet.
2671 ON_CALL(*disconnected_service.get(), technology())
2672 .WillByDefault(Return(Technology::kEthernet));
2673
2674 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002675 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002676 Error error;
2677 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2678
2679
2680 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002681 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002682 // Connected service should be brought to the front now.
2683 string expected_technology =
2684 Technology::NameFromIdentifier(Technology::kWifi);
2685 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2686}
2687
Paul Stewart212d60f2012-07-12 10:59:13 -07002688TEST_F(ManagerTest, Stop) {
2689 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002690 new NiceMock<MockProfile>(
2691 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002692 AdoptProfile(manager(), profile);
2693 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002694 new NiceMock<MockService>(control_interface(),
2695 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002696 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002697 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002698 manager()->RegisterService(service);
2699 manager()->RegisterDevice(mock_devices_[0]);
2700 EXPECT_CALL(*profile.get(),
2701 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2702 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002703 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002704 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2705 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002706 manager()->Stop();
2707}
2708
mukesh agrawal00917ce2011-11-22 23:56:55 +00002709TEST_F(ManagerTest, UpdateServiceConnected) {
2710 scoped_refptr<MockService> mock_service(
2711 new NiceMock<MockService>(control_interface(),
2712 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002713 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002714 manager()));
2715 manager()->RegisterService(mock_service);
2716 EXPECT_FALSE(mock_service->favorite());
2717 EXPECT_FALSE(mock_service->auto_connect());
2718
Gaurav Shah435de2c2011-11-17 19:01:07 -08002719 EXPECT_CALL(*mock_service.get(), IsConnected())
2720 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002721 manager()->UpdateService(mock_service);
2722 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2723 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002724 // SortServices test. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002725 EXPECT_TRUE(mock_service->favorite());
2726 EXPECT_TRUE(mock_service->auto_connect());
2727}
2728
Thieu Led4e9e552012-02-16 16:26:07 -08002729TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2730 // This tests the case where the user connects to a service that is
2731 // currently associated with a profile. We want to make sure that the
2732 // favorite flag is set and that the flag is saved to the current
2733 // profile.
2734 scoped_refptr<MockService> mock_service(
2735 new NiceMock<MockService>(control_interface(),
2736 dispatcher(),
2737 metrics(),
2738 manager()));
2739 manager()->RegisterService(mock_service);
2740 EXPECT_FALSE(mock_service->favorite());
2741 EXPECT_FALSE(mock_service->auto_connect());
2742
Gary Moraind93615e2012-04-27 11:50:03 -07002743 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002744 new MockProfile(
2745 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002746
Gary Moraind93615e2012-04-27 11:50:03 -07002747 mock_service->set_profile(profile);
2748 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002749 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002750 EXPECT_CALL(*profile,
2751 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002752 manager()->UpdateService(mock_service);
2753 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2754 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002755 // SortServices test. (crbug.com/206367)
Thieu Led4e9e552012-02-16 16:26:07 -08002756 EXPECT_TRUE(mock_service->favorite());
2757 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002758 // This releases the ref on the mock profile.
2759 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002760}
2761
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002762TEST_F(ManagerTest, SaveSuccessfulService) {
2763 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002764 new StrictMock<MockProfile>(
2765 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002766 AdoptProfile(manager(), profile);
2767 scoped_refptr<MockService> service(
2768 new NiceMock<MockService>(control_interface(),
2769 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002770 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002771 manager()));
2772
2773 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2774 ServiceRefPtr expect_service(service.get());
2775
2776 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2777 .WillOnce(Return(false));
2778 manager()->RegisterService(service);
2779
2780 EXPECT_CALL(*service.get(), state())
2781 .WillRepeatedly(Return(Service::kStateConnected));
2782 EXPECT_CALL(*service.get(), IsConnected())
2783 .WillRepeatedly(Return(true));
2784 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2785 .WillOnce(Return(true));
2786 manager()->UpdateService(service);
2787}
2788
Darin Petkove7c6ad32012-06-29 10:22:09 +02002789TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002790 MockProfile *profile0 =
2791 new MockProfile(control_interface(), metrics(), manager(), "");
2792 MockProfile *profile1 =
2793 new MockProfile(control_interface(), metrics(), manager(), "");
2794 MockProfile *profile2 =
2795 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002796 AdoptProfile(manager(), profile0); // Passes ownership.
2797 AdoptProfile(manager(), profile1); // Passes ownership.
2798 AdoptProfile(manager(), profile2); // Passes ownership.
2799 DeviceRefPtr device_ref(mock_devices_[0].get());
2800 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2801 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2802 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2803 manager()->UpdateDevice(mock_devices_[0]);
2804}
2805
Paul Stewart1b253142012-01-26 14:05:52 -08002806TEST_F(ManagerTest, EnumerateProfiles) {
2807 vector<string> profile_paths;
2808 for (size_t i = 0; i < 10; i++) {
2809 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002810 new StrictMock<MockProfile>(
2811 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002812 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002813 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2814 .WillOnce(Return(profile_paths.back()));
2815 AdoptProfile(manager(), profile);
2816 }
2817
2818 Error error;
2819 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2820 EXPECT_TRUE(error.IsSuccess());
2821 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2822 for (size_t i = 0; i < profile_paths.size(); i++) {
2823 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2824 }
2825}
2826
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002827TEST_F(ManagerTest, AutoConnectOnRegister) {
2828 MockServiceRefPtr service = MakeAutoConnectableService();
2829 EXPECT_CALL(*service.get(), AutoConnect());
2830 manager()->RegisterService(service);
2831 dispatcher()->DispatchPendingEvents();
2832}
2833
2834TEST_F(ManagerTest, AutoConnectOnUpdate) {
2835 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002836 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002837 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002838 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002839 manager()->RegisterService(service1);
2840 manager()->RegisterService(service2);
2841 dispatcher()->DispatchPendingEvents();
2842
2843 EXPECT_CALL(*service1.get(), AutoConnect());
2844 EXPECT_CALL(*service2.get(), state())
2845 .WillRepeatedly(Return(Service::kStateFailure));
2846 EXPECT_CALL(*service2.get(), IsFailed())
2847 .WillRepeatedly(Return(true));
2848 EXPECT_CALL(*service2.get(), IsConnected())
2849 .WillRepeatedly(Return(false));
2850 manager()->UpdateService(service2);
2851 dispatcher()->DispatchPendingEvents();
2852}
2853
2854TEST_F(ManagerTest, AutoConnectOnDeregister) {
2855 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002856 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002857 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002858 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002859 manager()->RegisterService(service1);
2860 manager()->RegisterService(service2);
2861 dispatcher()->DispatchPendingEvents();
2862
2863 EXPECT_CALL(*service1.get(), AutoConnect());
2864 manager()->DeregisterService(service2);
2865 dispatcher()->DispatchPendingEvents();
2866}
2867
Darin Petkov3ec55342012-09-28 14:04:44 +02002868TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2869 MockServiceRefPtr service = MakeAutoConnectableService();
2870 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2871 SetPowerManager();
2872 EXPECT_CALL(*service, AutoConnect()).Times(0);
2873 manager()->RegisterService(service);
2874 dispatcher()->DispatchPendingEvents();
2875}
2876
Darin Petkovca621542012-07-25 14:25:56 +02002877TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2878 MockServiceRefPtr service = MakeAutoConnectableService();
2879 SetPowerState(PowerManagerProxyDelegate::kMem);
2880 SetPowerManager();
2881 EXPECT_CALL(*service, AutoConnect()).Times(0);
2882 manager()->RegisterService(service);
2883 dispatcher()->DispatchPendingEvents();
2884}
2885
2886TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2887 MockServiceRefPtr service = MakeAutoConnectableService();
2888 SetPowerState(PowerManagerProxyDelegate::kOn);
2889 SetPowerManager();
2890 EXPECT_CALL(*service, AutoConnect());
2891 manager()->RegisterService(service);
2892 dispatcher()->DispatchPendingEvents();
2893}
2894
2895TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2896 MockServiceRefPtr service = MakeAutoConnectableService();
2897 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2898 SetPowerManager();
2899 EXPECT_CALL(*service, AutoConnect());
2900 manager()->RegisterService(service);
2901 dispatcher()->DispatchPendingEvents();
2902}
2903
Paul Stewart63864b62012-11-07 15:10:55 -08002904TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2905 SetRunning(false);
2906 MockServiceRefPtr service = MakeAutoConnectableService();
2907 EXPECT_CALL(*service, AutoConnect()).Times(0);
2908 manager()->RegisterService(service);
2909 dispatcher()->DispatchPendingEvents();
2910}
2911
Darin Petkovca621542012-07-25 14:25:56 +02002912TEST_F(ManagerTest, OnPowerStateChanged) {
2913 MockServiceRefPtr service = MakeAutoConnectableService();
2914 SetPowerState(PowerManagerProxyDelegate::kOn);
2915 SetPowerManager();
2916 EXPECT_CALL(*service, AutoConnect());
2917 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002918 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002919 dispatcher()->DispatchPendingEvents();
2920
mukesh agrawal784566d2012-08-08 18:32:58 -07002921 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002922 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2923 EXPECT_CALL(*service, AutoConnect());
2924 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002925 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002926
mukesh agrawal784566d2012-08-08 18:32:58 -07002927 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002928 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2929 EXPECT_CALL(*service, AutoConnect()).Times(0);
2930 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002931 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002932}
2933
Darin Petkov3ec55342012-09-28 14:04:44 +02002934TEST_F(ManagerTest, AddTerminationAction) {
2935 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002936 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002937 SetPowerManager();
2938 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2939 manager()->AddTerminationAction("action1", base::Closure());
2940 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2941 manager()->AddTerminationAction("action2", base::Closure());
2942}
2943
2944TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002945 const char kKey1[] = "action1";
2946 const char kKey2[] = "action2";
2947 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002948
2949 MockPowerManager &power_manager = *power_manager_;
2950 SetPowerManager();
2951
2952 // Removing an action when the hook table is empty should not result in any
2953 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002954 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002955 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2956 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2957 manager()->RemoveTerminationAction("unknown");
2958 Mock::VerifyAndClearExpectations(&power_manager);
2959
Daniel Eratf9753672013-01-24 10:17:02 -08002960 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2961 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002962 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002963 manager()->AddTerminationAction(kKey1, base::Closure());
2964 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2965 manager()->AddTerminationAction(kKey2, base::Closure());
2966
2967 // Removing an action that ends up with a non-empty hook table should not
2968 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002969 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002970 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2971 manager()->RemoveTerminationAction(kKey1);
2972 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2973 Mock::VerifyAndClearExpectations(&power_manager);
2974
2975 // Removing the last action should trigger unregistering from the power
2976 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002977 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2978 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002979 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2980 manager()->RemoveTerminationAction(kKey2);
2981 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2982}
2983
2984TEST_F(ManagerTest, RunTerminationActions) {
2985 TerminationActionTest test_action;
2986 const string kActionName = "action";
2987
2988 EXPECT_CALL(test_action, Done(_));
2989 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2990 test_action.AsWeakPtr()));
2991
2992 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2993 Bind(&TerminationActionTest::Action,
2994 test_action.AsWeakPtr()));
2995 test_action.set_manager(manager());
2996 EXPECT_CALL(test_action, Done(_));
2997 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2998 test_action.AsWeakPtr()));
2999}
3000
Daniel Erat0818cca2012-12-14 10:16:21 -08003001TEST_F(ManagerTest, OnSuspendImminent) {
3002 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02003003 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08003004 EXPECT_CALL(*power_manager_,
3005 ReportSuspendReadiness(
3006 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003007 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003008 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02003009}
3010
3011TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08003012 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02003013 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08003014 EXPECT_CALL(*power_manager_,
3015 ReportSuspendReadiness(
3016 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003017 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003018 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02003019}
3020
Paul Stewartc681fa02012-03-02 19:40:04 -08003021TEST_F(ManagerTest, RecheckPortal) {
3022 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
3023 .WillOnce(Return(false));
3024 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
3025 .WillOnce(Return(true));
3026 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
3027 .Times(0);
3028
3029 manager()->RegisterDevice(mock_devices_[0]);
3030 manager()->RegisterDevice(mock_devices_[1]);
3031 manager()->RegisterDevice(mock_devices_[2]);
3032
3033 manager()->RecheckPortal(NULL);
3034}
3035
Paul Stewartd215af62012-04-24 23:25:50 -07003036TEST_F(ManagerTest, RecheckPortalOnService) {
3037 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
3038 dispatcher(),
3039 metrics(),
3040 manager());
3041 EXPECT_CALL(*mock_devices_[0].get(),
3042 IsConnectedToService(IsRefPtrTo(service)))
3043 .WillOnce(Return(false));
3044 EXPECT_CALL(*mock_devices_[1].get(),
3045 IsConnectedToService(IsRefPtrTo(service)))
3046 .WillOnce(Return(true));
3047 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
3048 .WillOnce(Return(true));
3049 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
3050 .Times(0);
3051
3052 manager()->RegisterDevice(mock_devices_[0]);
3053 manager()->RegisterDevice(mock_devices_[1]);
3054 manager()->RegisterDevice(mock_devices_[2]);
3055
3056 manager()->RecheckPortalOnService(service);
3057}
3058
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003059TEST_F(ManagerTest, GetDefaultService) {
3060 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003061 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003062
3063 scoped_refptr<MockService> mock_service(
3064 new NiceMock<MockService>(control_interface(),
3065 dispatcher(),
3066 metrics(),
3067 manager()));
3068
3069 manager()->RegisterService(mock_service);
3070 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003071 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003072
3073 scoped_refptr<MockConnection> mock_connection(
3074 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07003075 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003076 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003077 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003078
Paul Stewartce4ec192012-03-14 12:53:46 -07003079 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003080 manager()->DeregisterService(mock_service);
3081}
3082
Paul Stewart13ed2252012-03-21 12:52:46 -07003083TEST_F(ManagerTest, GetServiceWithGUID) {
3084 scoped_refptr<MockService> mock_service0(
3085 new NiceMock<MockService>(control_interface(),
3086 dispatcher(),
3087 metrics(),
3088 manager()));
3089
3090 scoped_refptr<MockService> mock_service1(
3091 new NiceMock<MockService>(control_interface(),
3092 dispatcher(),
3093 metrics(),
3094 manager()));
3095
Paul Stewartcb59fed2012-03-21 21:14:46 -07003096 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3097 .Times(0);
3098 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3099 .Times(0);
3100
Paul Stewart13ed2252012-03-21 12:52:46 -07003101 manager()->RegisterService(mock_service0);
3102 manager()->RegisterService(mock_service1);
3103
3104 const string kGUID0 = "GUID0";
3105 const string kGUID1 = "GUID1";
3106
3107 {
3108 Error error;
3109 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3110 EXPECT_FALSE(error.IsSuccess());
3111 EXPECT_FALSE(service);
3112 }
3113
3114 KeyValueStore args;
3115 args.SetString(flimflam::kGuidProperty, kGUID1);
3116
3117 {
3118 Error error;
3119 ServiceRefPtr service = manager()->GetService(args, &error);
3120 EXPECT_EQ(Error::kInvalidArguments, error.type());
3121 EXPECT_FALSE(service);
3122 }
3123
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003124 mock_service0->SetGuid(kGUID0, NULL);
3125 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003126
3127 {
3128 Error error;
3129 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3130 EXPECT_TRUE(error.IsSuccess());
3131 EXPECT_EQ(mock_service0.get(), service.get());
3132 }
3133
3134 {
3135 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003136 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3137 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003138 ServiceRefPtr service = manager()->GetService(args, &error);
3139 EXPECT_TRUE(error.IsSuccess());
3140 EXPECT_EQ(mock_service1.get(), service.get());
3141 }
3142
3143 manager()->DeregisterService(mock_service0);
3144 manager()->DeregisterService(mock_service1);
3145}
3146
Gary Morain028545d2012-04-07 14:55:52 -07003147
3148TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003149 EXPECT_FALSE(manager()->IsOnline());
3150 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3151
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003152 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003153 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003154 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3155 .Times(AnyNumber());
3156 scoped_refptr<MockService> mock_service0(
3157 new NiceMock<MockService>(control_interface(),
3158 dispatcher(),
3159 metrics(),
3160 manager()));
3161
3162 scoped_refptr<MockService> mock_service1(
3163 new NiceMock<MockService>(control_interface(),
3164 dispatcher(),
3165 metrics(),
3166 manager()));
3167
3168 EXPECT_CALL(*mock_service0.get(), IsConnected())
3169 .WillRepeatedly(Return(false));
3170 EXPECT_CALL(*mock_service1.get(), IsConnected())
3171 .WillRepeatedly(Return(false));
3172
3173 manager()->RegisterService(mock_service0);
3174 manager()->RegisterService(mock_service1);
3175
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003176 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003177 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3178
3179 manager()->DeregisterService(mock_service0);
3180 manager()->DeregisterService(mock_service1);
3181}
3182
3183TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003184 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003185 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003186 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3187 .Times(AnyNumber());
3188 scoped_refptr<MockService> mock_service0(
3189 new NiceMock<MockService>(control_interface(),
3190 dispatcher(),
3191 metrics(),
3192 manager()));
3193
3194 scoped_refptr<MockService> mock_service1(
3195 new NiceMock<MockService>(control_interface(),
3196 dispatcher(),
3197 metrics(),
3198 manager()));
3199
3200 EXPECT_CALL(*mock_service0.get(), IsConnected())
3201 .WillRepeatedly(Return(false));
3202 EXPECT_CALL(*mock_service1.get(), IsConnected())
3203 .WillRepeatedly(Return(true));
3204 EXPECT_CALL(*mock_service0.get(), state())
3205 .WillRepeatedly(Return(Service::kStateIdle));
3206 EXPECT_CALL(*mock_service1.get(), state())
3207 .WillRepeatedly(Return(Service::kStateConnected));
3208
3209 manager()->RegisterService(mock_service0);
3210 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003211 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003212
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003213 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003214 EXPECT_EQ("online", manager()->CalculateState(NULL));
3215
3216 manager()->DeregisterService(mock_service0);
3217 manager()->DeregisterService(mock_service1);
3218}
3219
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003220TEST_F(ManagerTest, StartupPortalList) {
3221 // Simulate loading value from the default profile.
3222 const string kProfileValue("wifi,vpn");
3223 manager()->props_.check_portal_list = kProfileValue;
3224
3225 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3226 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3227 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3228
3229 const string kStartupValue("cellular,ethernet");
3230 manager()->SetStartupPortalList(kStartupValue);
3231 // Ensure profile value is not overwritten, so when we save the default
3232 // profile, the correct value will still be written.
3233 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3234
3235 // However we should read back a different list.
3236 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3237 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3238 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3239
3240 const string kRuntimeValue("ppp");
3241 // Setting a runtime value over the control API should overwrite both
3242 // the profile value and what we read back.
3243 Error error;
3244 manager()->mutable_store()->SetStringProperty(
3245 flimflam::kCheckPortalListProperty,
3246 kRuntimeValue,
3247 &error);
3248 ASSERT_TRUE(error.IsSuccess());
3249 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3250 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3251 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3252 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3253}
3254
Paul Stewart036dba02012-08-07 12:34:41 -07003255TEST_F(ManagerTest, LinkMonitorEnabled) {
3256 const string kEnabledTechnologies("wifi,vpn");
3257 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3258 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3259 EXPECT_FALSE(
3260 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3261}
3262
Paul Stewart85aea152013-01-22 09:31:56 -08003263TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003264 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003265 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003266 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003267 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003268 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003269 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3270 AdoptProfile(manager(), profile);
3271 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3272 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3273 scoped_ptr<MockStore> store1(new MockStore);
3274 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3275}
3276
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003277TEST_F(ManagerTest, SetEnabledStateForTechnology) {
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003278 Error error(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003279 DisableTechnologyReplyHandler disable_technology_reply_handler;
3280 ResultCallback disable_technology_callback(
3281 Bind(&DisableTechnologyReplyHandler::ReportResult,
3282 disable_technology_reply_handler.AsWeakPtr()));
3283 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_)).Times(0);
3284
3285 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3286 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003287 EXPECT_TRUE(error.IsSuccess());
3288
Joshua Krollda798622012-06-05 12:30:48 -07003289 ON_CALL(*mock_devices_[0], technology())
3290 .WillByDefault(Return(Technology::kEthernet));
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003291 ON_CALL(*mock_devices_[1], technology())
3292 .WillByDefault(Return(Technology::kCellular));
3293 ON_CALL(*mock_devices_[2], technology())
3294 .WillByDefault(Return(Technology::kCellular));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003295
3296 manager()->RegisterDevice(mock_devices_[0]);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003297 manager()->RegisterDevice(mock_devices_[1]);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003298
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003299 // Ethernet Device is disabled, so disable succeeds immediately.
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003300 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003301 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3302 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003303 EXPECT_TRUE(error.IsSuccess());
3304
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003305 // Ethernet Device is enabled, and mock doesn't change error from
3306 // kOperationInitiated, so expect disable to say operation in progress.
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003307 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3308 mock_devices_[0]->enabled_ = true;
3309 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003310 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3311 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003312 EXPECT_TRUE(error.IsOngoing());
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003313
3314 // Ethernet Device is disabled, and mock doesn't change error from
3315 // kOperationInitiated, so expect enable to say operation in progress.
3316 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3317 mock_devices_[0]->enabled_ = false;
3318 error.Populate(Error::kOperationInitiated);
3319 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, true,
3320 &error, disable_technology_callback);
3321 EXPECT_TRUE(error.IsOngoing());
3322
3323 // Cellular Device is enabled, but disable failed.
3324 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3325 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3326 mock_devices_[1]->enabled_ = true;
3327 error.Populate(Error::kOperationInitiated);
3328 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3329 &error, disable_technology_callback);
3330 EXPECT_EQ(Error::kPermissionDenied, error.type());
3331
3332 // Multiple Cellular Devices in enabled state. Should indicate IsOngoing
3333 // if one is in progress (even if the other completed immediately).
3334 manager()->RegisterDevice(mock_devices_[2]);
3335 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3336 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3337 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _));
3338 mock_devices_[1]->enabled_ = true;
3339 mock_devices_[2]->enabled_ = true;
3340 error.Populate(Error::kOperationInitiated);
3341 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3342 &error, disable_technology_callback);
3343 EXPECT_TRUE(error.IsOngoing());
3344
3345 // ...and order doesn't matter.
3346 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _));
3347 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3348 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3349 mock_devices_[1]->enabled_ = true;
3350 mock_devices_[2]->enabled_ = true;
3351 error.Populate(Error::kOperationInitiated);
3352 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3353 &error, disable_technology_callback);
3354 EXPECT_TRUE(error.IsOngoing());
3355 Mock::VerifyAndClearExpectations(&disable_technology_reply_handler);
3356
3357 // Multiple Cellular Devices in enabled state. Even if all disable
3358 // operations complete asynchronously, we only get one call to the
3359 // DisableTechnologyReplyHandler::ReportResult.
3360 ResultCallback device1_result_callback;
3361 ResultCallback device2_result_callback;
3362 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3363 .WillOnce(SaveArg<2>(&device1_result_callback));
3364 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3365 .WillOnce(DoAll(WithArg<1>(Invoke(SetErrorPermissionDenied)),
3366 SaveArg<2>(&device2_result_callback)));
3367 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_));
3368 mock_devices_[1]->enabled_ = true;
3369 mock_devices_[2]->enabled_ = true;
3370 error.Populate(Error::kOperationInitiated);
3371 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3372 &error, disable_technology_callback);
3373 EXPECT_TRUE(error.IsOngoing());
3374 device1_result_callback.Run(Error(Error::kSuccess));
3375 device2_result_callback.Run(Error(Error::kSuccess));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003376}
3377
Paul Stewart4d5efb72012-09-17 12:24:34 -07003378TEST_F(ManagerTest, IgnoredSearchList) {
3379 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003380 vector<string> ignored_paths;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003381 SetResolver(resolver.get());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003382
3383 const string kIgnored0 = "chromium.org";
3384 ignored_paths.push_back(kIgnored0);
3385 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003386 SetIgnoredDNSSearchPaths(kIgnored0, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003387 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3388
3389 const string kIgnored1 = "google.com";
3390 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3391 ignored_paths.push_back(kIgnored1);
3392 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003393 SetIgnoredDNSSearchPaths(kIgnoredSum, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003394 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3395
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003396 ignored_paths.clear();
3397 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3398 SetIgnoredDNSSearchPaths("", NULL);
3399 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3400
Paul Stewart4d5efb72012-09-17 12:24:34 -07003401 SetResolver(Resolver::GetInstance());
3402}
3403
Paul Stewartbfb82552012-10-24 16:48:48 -07003404TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3405 // Test to make sure that every service state-change causes the
3406 // Manager to emit a new service list.
3407 scoped_refptr<MockService> mock_service(
3408 new NiceMock<MockService>(control_interface(),
3409 dispatcher(),
3410 metrics(),
3411 manager()));
3412 EXPECT_CALL(*mock_service, state())
3413 .WillRepeatedly(Return(Service::kStateIdle));
3414
3415 manager()->RegisterService(mock_service);
3416 EXPECT_CALL(
3417 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3418 flimflam::kServicesProperty, _)).Times(1);
3419 EXPECT_CALL(
3420 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3421 flimflam::kServiceWatchListProperty, _)).Times(1);
3422 CompleteServiceSort();
3423
3424 Mock::VerifyAndClearExpectations(manager_adaptor_);
3425 EXPECT_CALL(
3426 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3427 flimflam::kServicesProperty, _)).Times(1);
3428 EXPECT_CALL(
3429 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3430 flimflam::kServiceWatchListProperty, _)).Times(1);
3431 manager()->UpdateService(mock_service.get());
3432 CompleteServiceSort();
3433
3434 manager()->DeregisterService(mock_service);
3435}
3436
3437TEST_F(ManagerTest, EnumerateServices) {
3438 scoped_refptr<MockService> mock_service(
3439 new NiceMock<MockService>(control_interface(),
3440 dispatcher(),
3441 metrics(),
3442 manager()));
3443 manager()->RegisterService(mock_service);
3444
3445 EXPECT_CALL(*mock_service, state())
3446 .WillRepeatedly(Return(Service::kStateConnected));
3447 EXPECT_CALL(*mock_service, IsVisible())
3448 .WillRepeatedly(Return(false));
3449 EXPECT_TRUE(EnumerateAvailableServices().empty());
3450 EXPECT_TRUE(EnumerateWatchedServices().empty());
3451
3452 EXPECT_CALL(*mock_service, state())
3453 .WillRepeatedly(Return(Service::kStateIdle));
3454 EXPECT_TRUE(EnumerateAvailableServices().empty());
3455 EXPECT_TRUE(EnumerateWatchedServices().empty());
3456
3457 EXPECT_CALL(*mock_service, IsVisible())
3458 .WillRepeatedly(Return(true));
3459 Service::ConnectState unwatched_states[] = {
3460 Service::kStateUnknown,
3461 Service::kStateIdle,
3462 Service::kStateFailure
3463 };
3464 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3465 EXPECT_CALL(*mock_service, state())
3466 .WillRepeatedly(Return(unwatched_states[i]));
3467 EXPECT_FALSE(EnumerateAvailableServices().empty());
3468 EXPECT_TRUE(EnumerateWatchedServices().empty());
3469 }
3470
3471 Service::ConnectState watched_states[] = {
3472 Service::kStateAssociating,
3473 Service::kStateConfiguring,
3474 Service::kStateConnected,
Paul Stewartbfb82552012-10-24 16:48:48 -07003475 Service::kStatePortal,
3476 Service::kStateOnline
3477 };
3478 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3479 EXPECT_CALL(*mock_service, state())
3480 .WillRepeatedly(Return(watched_states[i]));
3481 EXPECT_FALSE(EnumerateAvailableServices().empty());
3482 EXPECT_FALSE(EnumerateWatchedServices().empty());
3483 }
3484
3485 manager()->DeregisterService(mock_service);
3486}
3487
Paul Stewart39db5ca2013-03-18 14:15:17 -07003488TEST_F(ManagerTest, ConnectToBestServices) {
3489 scoped_refptr<MockService> wifi_service0(
3490 new NiceMock<MockService>(control_interface(),
3491 dispatcher(),
3492 metrics(),
3493 manager()));
3494 EXPECT_CALL(*wifi_service0.get(), state())
3495 .WillRepeatedly(Return(Service::kStateIdle));
3496 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3497 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003498 wifi_service0->SetConnectable(true);
3499 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003500 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3501 EXPECT_CALL(*wifi_service0.get(), technology())
3502 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003503 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3504 .WillRepeatedly(Return(false));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003505 EXPECT_CALL(*wifi_service0.get(), explicitly_disconnected())
3506 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003507
3508 scoped_refptr<MockService> wifi_service1(
3509 new NiceMock<MockService>(control_interface(),
3510 dispatcher(),
3511 metrics(),
3512 manager()));
3513 EXPECT_CALL(*wifi_service1.get(), state())
3514 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003515 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3516 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003517 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3518 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003519 wifi_service1->SetAutoConnect(true);
3520 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003521 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3522 EXPECT_CALL(*wifi_service1.get(), technology())
3523 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003524 EXPECT_CALL(*wifi_service1.get(), explicitly_disconnected())
3525 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003526
3527 scoped_refptr<MockService> wifi_service2(
3528 new NiceMock<MockService>(control_interface(),
3529 dispatcher(),
3530 metrics(),
3531 manager()));
3532 EXPECT_CALL(*wifi_service2.get(), state())
3533 .WillRepeatedly(Return(Service::kStateConnected));
3534 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3535 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003536 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3537 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003538 wifi_service2->SetAutoConnect(true);
3539 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003540 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3541 EXPECT_CALL(*wifi_service2.get(), technology())
3542 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003543 EXPECT_CALL(*wifi_service2.get(), explicitly_disconnected())
3544 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003545
3546 manager()->RegisterService(wifi_service0);
3547 manager()->RegisterService(wifi_service1);
3548 manager()->RegisterService(wifi_service2);
3549
3550 CompleteServiceSort();
3551 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3552
3553 scoped_refptr<MockService> cell_service(
3554 new NiceMock<MockService>(control_interface(),
3555 dispatcher(),
3556 metrics(),
3557 manager()));
3558
3559 EXPECT_CALL(*cell_service.get(), state())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003560 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003561 EXPECT_CALL(*cell_service.get(), IsConnected())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003562 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003563 EXPECT_CALL(*cell_service.get(), IsVisible())
3564 .WillRepeatedly(Return(true));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003565 cell_service->SetAutoConnect(true);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003566 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003567 EXPECT_CALL(*cell_service.get(), technology())
3568 .WillRepeatedly(Return(Technology::kCellular));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003569 EXPECT_CALL(*cell_service.get(), explicitly_disconnected())
3570 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003571 manager()->RegisterService(cell_service);
3572
Arman Uguray6fe4f262013-08-02 20:21:55 -07003573 scoped_refptr<MockService> wimax_service(
3574 new NiceMock<MockService>(control_interface(),
3575 dispatcher(),
3576 metrics(),
3577 manager()));
3578
3579 EXPECT_CALL(*wimax_service.get(), state())
3580 .WillRepeatedly(Return(Service::kStateConnected));
3581 EXPECT_CALL(*wimax_service.get(), IsConnected())
3582 .WillRepeatedly(Return(true));
3583 EXPECT_CALL(*wimax_service.get(), IsVisible())
3584 .WillRepeatedly(Return(true));
3585 wimax_service->SetAutoConnect(true);
3586 wimax_service->SetConnectable(true);
3587 EXPECT_CALL(*wimax_service.get(), technology())
3588 .WillRepeatedly(Return(Technology::kWiMax));
3589 EXPECT_CALL(*wimax_service.get(), explicitly_disconnected())
3590 .WillRepeatedly(Return(false));
3591 manager()->RegisterService(wimax_service);
3592
Paul Stewart39db5ca2013-03-18 14:15:17 -07003593 scoped_refptr<MockService> vpn_service(
3594 new NiceMock<MockService>(control_interface(),
3595 dispatcher(),
3596 metrics(),
3597 manager()));
3598
3599 EXPECT_CALL(*vpn_service.get(), state())
3600 .WillRepeatedly(Return(Service::kStateIdle));
3601 EXPECT_CALL(*vpn_service.get(), IsConnected())
3602 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003603 EXPECT_CALL(*vpn_service.get(), IsVisible())
3604 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003605 wifi_service2->SetAutoConnect(false);
3606 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003607 EXPECT_CALL(*vpn_service.get(), technology())
3608 .WillRepeatedly(Return(Technology::kVPN));
3609 manager()->RegisterService(vpn_service);
3610
3611 // The connected services should be at the top.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003612 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003613
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003614 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3615 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003616 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003617 EXPECT_CALL(*cell_service.get(), Connect(_, _))
3618 .Times(0); // Explicitly disconnected.
3619 EXPECT_CALL(*wimax_service.get(), Connect(_, _)).Times(0); // Is connected.
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003620 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003621
3622 manager()->ConnectToBestServices(NULL);
3623 dispatcher()->DispatchPendingEvents();
3624
3625 // After this operation, since the Connect calls above are mocked and
3626 // no actual state changes have occurred, we should expect that the
3627 // service sorting order will not have changed.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003628 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003629}
3630
Christopher Wiley83889862013-05-02 15:55:09 -07003631TEST_F(ManagerTest, VerifyWhenNotConnected) {
3632 const string kFakeCertificate("fake cert");
3633 const string kFakePublicKey("fake public key");
3634 const string kFakeNonce("fake public key");
3635 const string kFakeSignedData("fake signed data");
3636 const string kFakeUdn("fake udn");
3637 const vector<uint8_t> kSSID(10, 87);
3638 const string kConfiguredSSID("AConfiguredDestination");
3639 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3640 kConfiguredSSID.end());
3641 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
3642 scoped_refptr<MockWiFiService> mock_destination(
3643 new NiceMock<MockWiFiService>(control_interface(), dispatcher(),
3644 metrics(), manager(), wifi_provider_,
3645 kSSID, "", "none", false));
3646 // Register this service, but don't mark it as connected.
3647 manager()->RegisterService(mock_destination);
3648 // Verify that if we're not connected to anything, verification fails.
3649 {
3650 LOG(INFO) << "Can't verify if not connected.";
3651 EXPECT_CALL(*crypto_util_proxy_,
3652 VerifyDestination(_, _, _, _, _, _, _, _, _)).Times(0);
3653 Error error(Error::kOperationInitiated);
3654 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3655 kFakeSignedData, kFakeUdn, "", "",
3656 ResultBoolCallback(), &error);
3657 EXPECT_TRUE(error.IsFailure());
3658 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3659 }
3660 {
3661 // However, if the destination is already configured, we might be
3662 // connected to it via something other than WiFi, and we shouldn't
3663 // enforce the WiFi check.
3664 EXPECT_CALL(*crypto_util_proxy_,
3665 VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3666 kFakeSignedData, kFakeUdn,
3667 kConfiguredSSIDVector, kConfiguredBSSID,
3668 _, _)).Times(1).WillOnce(Return(true));
3669 Error error(Error::kOperationInitiated);
3670 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3671 kFakeSignedData, kFakeUdn, kConfiguredSSID,
3672 kConfiguredBSSID, ResultBoolCallback(),
3673 &error);
3674 EXPECT_FALSE(error.IsFailure());
3675 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3676 }
3677}
3678
Christopher Wiley1057cd72013-02-28 15:21:29 -08003679TEST_F(ManagerTest, VerifyDestination) {
3680 const string kFakeCertificate("fake cert");
3681 const string kFakePublicKey("fake public key");
3682 const string kFakeNonce("fake public key");
3683 const string kFakeSignedData("fake signed data");
3684 const string kFakeUdn("fake udn");
3685 const char kSSIDStr[] = "fake ssid";
3686 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
Christopher Wileycdde79f2013-05-01 14:26:56 -07003687 const string kConfiguredSSID("AConfiguredDestination");
3688 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3689 kConfiguredSSID.end());
3690 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
Christopher Wiley1057cd72013-02-28 15:21:29 -08003691 const string kFakeData("muffin man");
3692 scoped_refptr<MockWiFiService> mock_destination(
3693 new NiceMock<MockWiFiService>(control_interface(),
3694 dispatcher(),
3695 metrics(),
3696 manager(),
3697 wifi_provider_,
3698 kSSID,
3699 "",
3700 "none",
3701 false));
3702 manager()->RegisterService(mock_destination);
Christopher Wiley1057cd72013-02-28 15:21:29 -08003703 // Making the service look online will let service lookup in
3704 // VerifyDestinatoin succeed.
3705 EXPECT_CALL(*mock_destination.get(), IsConnected())
3706 .WillRepeatedly(Return(true));
Christopher Wiley83889862013-05-02 15:55:09 -07003707 StrictMock<DestinationVerificationTest> dv_test;
Christopher Wiley1057cd72013-02-28 15:21:29 -08003708
3709 // Lead off by verifying that the basic VerifyDestination flow works.
3710 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003711 LOG(INFO) << "Basic VerifyDestination flow.";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003712 ResultBoolCallback passed_down_callback;
3713 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3714 kFakePublicKey,
3715 kFakeNonce,
3716 kFakeSignedData,
3717 kFakeUdn,
3718 kSSID,
3719 _,
3720 _,
3721 _))
3722 .Times(1)
3723 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3724 // Ask the manager to verify the current destination. This should look
3725 // up our previously registered service, and pass some metadata about
3726 // that service down to the CryptoUtilProxy to verify.
3727 Error error(Error::kOperationInitiated);
3728 ResultBoolCallback cb = Bind(
3729 &DestinationVerificationTest::ResultBoolCallbackStub,
3730 dv_test.AsWeakPtr());
3731 manager()->VerifyDestination(kFakeCertificate,
3732 kFakePublicKey,
3733 kFakeNonce,
3734 kFakeSignedData,
3735 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003736 // Ask to be verified against that service.
3737 "", "",
3738 cb,
3739 &error);
3740 // We assert here, because if the operation is not ongoing, it is
3741 // inconsistent with shim behavior to call the callback anyway.
3742 ASSERT_TRUE(error.IsOngoing());
3743 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3744 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3745 // Call the callback passed into the CryptoUtilProxy, which
3746 // should find its way into the callback passed into the manager.
3747 // In real code, that callback passed into the manager is from the
3748 // DBus adaptor.
3749 Error e;
3750 passed_down_callback.Run(e, true);
3751 Mock::VerifyAndClearExpectations(&dv_test);
3752 }
3753
Christopher Wiley1057cd72013-02-28 15:21:29 -08003754 // Now for a slightly more complex variant. When we encrypt data,
3755 // we do the same verification step but monkey with the callback to
3756 // link ourselves to an encrypt step afterward.
3757 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003758 LOG(INFO) << "Basic VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003759 ResultBoolCallback passed_down_callback;
3760 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3761 kFakePublicKey,
3762 kFakeNonce,
3763 kFakeSignedData,
3764 kFakeUdn,
3765 kSSID,
3766 _,
3767 _,
3768 _))
3769 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3770
3771 Error error(Error::kOperationInitiated);
3772 ResultStringCallback cb = Bind(
3773 &DestinationVerificationTest::ResultStringCallbackStub,
3774 dv_test.AsWeakPtr());
3775 manager()->VerifyAndEncryptData(kFakeCertificate,
3776 kFakePublicKey,
3777 kFakeNonce,
3778 kFakeSignedData,
3779 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003780 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003781 kFakeData,
3782 cb,
3783 &error);
3784 ASSERT_TRUE(error.IsOngoing());
3785 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3786 // Now, if we call that passed down callback, we should see encrypt being
3787 // called.
3788 ResultStringCallback second_passed_down_callback;
3789 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3790 kFakeData,
3791 _,
3792 _))
3793 .Times(1)
3794 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3795 Return(true)));
3796 Error e;
3797 passed_down_callback.Run(e, true);
3798 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3799 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3800 // And if we call the second passed down callback, we should see the
3801 // original function we passed down to VerifyDestination getting called.
3802 e.Reset();
3803 second_passed_down_callback.Run(e, "");
3804 Mock::VerifyAndClearExpectations(&dv_test);
3805 }
3806
3807 // If verification fails on the way to trying to encrypt, we should ditch
3808 // without calling encrypt at all.
3809 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003810 LOG(INFO) << "Failed VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003811 ResultBoolCallback passed_down_callback;
3812 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3813 kFakePublicKey,
3814 kFakeNonce,
3815 kFakeSignedData,
3816 kFakeUdn,
3817 kSSID,
3818 _,
3819 _,
3820 _))
3821 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3822
3823 Error error(Error::kOperationInitiated);
3824 ResultStringCallback cb = Bind(
3825 &DestinationVerificationTest::ResultStringCallbackStub,
3826 dv_test.AsWeakPtr());
3827 manager()->VerifyAndEncryptData(kFakeCertificate,
3828 kFakePublicKey,
3829 kFakeNonce,
3830 kFakeSignedData,
3831 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003832 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003833 kFakeData,
3834 cb,
3835 &error);
3836 ASSERT_TRUE(error.IsOngoing());
3837 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3838 Error e(Error::kOperationFailed);
3839 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3840 // Although we're ditching, this callback is what cleans up the pending
3841 // DBus call.
3842 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3843 passed_down_callback.Run(e, false);
3844 Mock::VerifyAndClearExpectations(&dv_test);
3845 }
3846}
3847
Paul Stewartd2e1c362013-03-03 19:06:07 -08003848TEST_F(ManagerTest, IsProfileBefore) {
3849 scoped_refptr<MockProfile> profile0(
3850 new NiceMock<MockProfile>(
3851 control_interface(), metrics(), manager(), ""));
3852 scoped_refptr<MockProfile> profile1(
3853 new NiceMock<MockProfile>(
3854 control_interface(), metrics(), manager(), ""));
3855
3856 AdoptProfile(manager(), profile0);
3857 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3858 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3859 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3860
3861 // A few abnormal cases, but it's good to track their behavior.
3862 scoped_refptr<MockProfile> profile2(
3863 new NiceMock<MockProfile>(
3864 control_interface(), metrics(), manager(), ""));
3865 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3866 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3867 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3868 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3869}
3870
Paul Stewart967eaeb2013-04-25 19:53:07 -07003871TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
3872 MockStore storage0;
3873 MockStore storage1;
3874 MockStore storage2;
3875
3876 scoped_refptr<MockProfile> profile0(
3877 new NiceMock<MockProfile>(
3878 control_interface(), metrics(), manager(), ""));
3879 scoped_refptr<MockProfile> profile1(
3880 new NiceMock<MockProfile>(
3881 control_interface(), metrics(), manager(), ""));
3882 scoped_refptr<MockProfile> profile2(
3883 new NiceMock<MockProfile>(
3884 control_interface(), metrics(), manager(), ""));
3885
3886 AdoptProfile(manager(), profile0);
3887 AdoptProfile(manager(), profile1);
3888 AdoptProfile(manager(), profile2);
3889
3890 scoped_refptr<MockService> service(
3891 new NiceMock<MockService>(control_interface(),
3892 dispatcher(),
3893 metrics(),
3894 manager()));
3895
3896 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
3897 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
3898 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
3899
3900 const string kEntry0("aluminum_crutch");
3901 const string kEntry2("rehashed_faces");
3902
3903 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
3904 .WillOnce(Return(kEntry0));
3905 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
3906 .WillOnce(Return(""));
3907 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
3908 .WillOnce(Return(kEntry2));
3909
3910 const string kProfileRpc0("service_station");
3911 const string kProfileRpc2("crystal_tiaras");
3912
3913 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
3914 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
3915 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
3916
3917 map<string, string> entries =
3918 manager()->GetLoadableProfileEntriesForService(service);
3919 EXPECT_EQ(2, entries.size());
3920 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
3921 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
3922 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
3923 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
3924}
3925
mukesh agrawal00752532013-05-03 15:46:55 -07003926TEST_F(ManagerTest, InitializeProfilesInformsProviders) {
mukesh agrawald142fd62013-05-01 16:50:57 -07003927 // We need a real glib here, so that profiles are persisted.
3928 GLib glib;
3929 ScopedTempDir temp_dir;
3930 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3931 Manager manager(control_interface(),
3932 dispatcher(),
3933 metrics(),
3934 &glib,
3935 run_path(),
3936 storage_path(),
3937 temp_dir.path().value());
3938 // Can't use |wifi_provider_|, because it's owned by the Manager
3939 // object in the fixture.
3940 MockWiFiProvider *wifi_provider = new NiceMock<MockWiFiProvider>();
3941 manager.wifi_provider_.reset(wifi_provider); // pass ownership
Paul Stewartb87d22b2013-07-29 11:11:37 -07003942 manager.UpdateProviderMapping();
mukesh agrawald142fd62013-05-01 16:50:57 -07003943 // Give manager a valid place to write the user profile list.
3944 manager.user_profile_list_path_ = temp_dir.path().Append("user_profile_list");
3945
3946 // With no user profiles, the WiFiProvider should be called once
3947 // (for the default profile).
3948 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_));
3949 manager.InitializeProfiles();
3950 Mock::VerifyAndClearExpectations(wifi_provider);
3951
3952 // With |n| user profiles, the WiFiProvider should be called |n+1|
3953 // times. First, create 2 user profiles...
3954 const char kProfile0[] = "~user/profile0";
3955 const char kProfile1[] = "~user/profile1";
3956 string profile_rpc_path;
3957 Error error;
3958 manager.CreateProfile(kProfile0, &profile_rpc_path, &error);
3959 manager.PushProfile(kProfile0, &profile_rpc_path, &error);
3960 manager.CreateProfile(kProfile1, &profile_rpc_path, &error);
3961 manager.PushProfile(kProfile1, &profile_rpc_path, &error);
3962
3963 // ... then reset manager state ...
3964 manager.profiles_.clear();
3965
3966 // ...then check that the WiFiProvider is notified about all three
3967 // profiles (one default, two user).
3968 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_)).Times(3);
3969 manager.InitializeProfiles();
3970 Mock::VerifyAndClearExpectations(wifi_provider);
3971}
3972
mukesh agrawal00752532013-05-03 15:46:55 -07003973TEST_F(ManagerTest, InitializeProfilesHandlesDefaults) {
3974 // We need a real glib here, so that profiles are persisted.
3975 GLib glib;
3976 ScopedTempDir temp_dir;
3977 scoped_ptr<Manager> manager;
3978 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3979
3980 // Instantiate a Manager with empty persistent storage. Check that
3981 // defaults are set.
3982 //
3983 // Note that we use the same directory for default and user profiles.
3984 // This doesn't affect the test results, because we don't push a
3985 // user profile.
3986 manager.reset(new Manager(control_interface(),
3987 dispatcher(),
3988 metrics(),
3989 &glib,
3990 run_path(),
3991 temp_dir.path().value(),
3992 temp_dir.path().value()));
3993 manager->InitializeProfiles();
3994 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
3995 manager->props_.check_portal_list);
3996 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
3997 manager->props_.ignored_dns_search_paths);
3998 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
3999 manager->props_.link_monitor_technologies);
4000 EXPECT_EQ(PortalDetector::kDefaultURL,
4001 manager->props_.portal_url);
4002 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
4003 manager->props_.portal_check_interval_seconds);
4004
4005 // Change one of the settings.
4006 static const string kCustomCheckPortalList = "fiber0";
4007 Error error;
4008 manager->SetCheckPortalList(kCustomCheckPortalList, &error);
4009 manager->profiles_[0]->Save();
4010
4011 // Instantiate a new manager. It should have our settings for
4012 // check_portal_list, rather than the default.
4013 manager.reset(new Manager(control_interface(),
4014 dispatcher(),
4015 metrics(),
4016 &glib,
4017 run_path(),
4018 temp_dir.path().value(),
4019 temp_dir.path().value()));
4020 manager->InitializeProfiles();
4021 EXPECT_EQ(kCustomCheckPortalList, manager->props_.check_portal_list);
4022
4023 // If we clear the persistent storage, we again get the default value.
4024 ASSERT_TRUE(temp_dir.Delete());
4025 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4026 manager.reset(new Manager(control_interface(),
4027 dispatcher(),
4028 metrics(),
4029 &glib,
4030 run_path(),
4031 temp_dir.path().value(),
4032 temp_dir.path().value()));
4033 manager->InitializeProfiles();
4034 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4035 manager->props_.check_portal_list);
4036}
4037
mukesh agrawalbebf1b82013-04-23 15:06:33 -07004038// Custom property setters should return false, and make no changes, if
4039// the new value is the same as the old value.
4040TEST_F(ManagerTest, CustomSetterNoopChange) {
4041 // SetCheckPortalList
4042 {
4043 static const string kCheckPortalList = "weird-device,weirder-device";
4044 Error error;
4045 // Set to known value.
4046 EXPECT_TRUE(SetCheckPortalList(kCheckPortalList, &error));
4047 EXPECT_TRUE(error.IsSuccess());
4048 // Set to same value.
4049 EXPECT_FALSE(SetCheckPortalList(kCheckPortalList, &error));
4050 EXPECT_TRUE(error.IsSuccess());
4051 }
4052
4053 // SetIgnoredDNSSearchPaths
4054 {
4055 NiceMock<MockResolver> resolver;
4056 static const string kIgnoredPaths = "example.com,example.org";
4057 Error error;
4058 SetResolver(&resolver);
4059 // Set to known value.
4060 EXPECT_CALL(resolver, set_ignored_search_list(_));
4061 EXPECT_TRUE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4062 EXPECT_TRUE(error.IsSuccess());
4063 Mock::VerifyAndClearExpectations(&resolver);
4064 // Set to same value.
4065 EXPECT_CALL(resolver, set_ignored_search_list(_)).Times(0);
4066 EXPECT_FALSE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4067 EXPECT_TRUE(error.IsSuccess());
4068 Mock::VerifyAndClearExpectations(&resolver);
4069 }
4070}
4071
Chris Masone9be4a9d2011-05-16 15:44:09 -07004072} // namespace shill