blob: fbd5f2f9821b4f130bfc3c29ffa99f9972b2e974 [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"
Paul Stewart7de7e022013-08-28 09:42:50 -070023#include "shill/geolocation_info.h"
Chris Masone6515aab2011-10-12 16:19:09 -070024#include "shill/glib.h"
25#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070026#include "shill/key_value_store.h"
mukesh agrawal00752532013-05-03 15:46:55 -070027#include "shill/link_monitor.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070028#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070029#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080030#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070031#include "shill/mock_control.h"
Christopher Wiley1057cd72013-02-28 15:21:29 -080032#include "shill/mock_crypto_util_proxy.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070033#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080034#include "shill/mock_device_info.h"
Paul Stewart35eff132013-04-12 12:08:40 -070035#include "shill/mock_ethernet_eap_provider.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070036#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000037#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020038#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070039#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070040#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070041#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070042#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080043#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070044#include "shill/mock_wifi_service.h"
mukesh agrawal00752532013-05-03 15:46:55 -070045#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070046#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020047#include "shill/proxy_factory.h"
mukesh agrawal00752532013-05-03 15:46:55 -070048#include "shill/resolver.h"
Chris Masone6515aab2011-10-12 16:19:09 -070049#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070050#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020051#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070052
Christopher Wiley1057cd72013-02-28 15:21:29 -080053using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080054using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080055using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070056using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070057using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070058using std::string;
59using std::vector;
60
Chris Masone9be4a9d2011-05-16 15:44:09 -070061namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070062using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070063using ::testing::AnyNumber;
Paul Stewart7de7e022013-08-28 09:42:50 -070064using ::testing::AtLeast;
Gaurav Shah435de2c2011-11-17 19:01:07 -080065using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070066using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070067using ::testing::InSequence;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070068using ::testing::Invoke;
mukesh agrawal784566d2012-08-08 18:32:58 -070069using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070070using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070071using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070072using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070073using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070074using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070075using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080076using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080077using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080078using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070079using ::testing::Test;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070080using ::testing::WithArg;
Chris Masone9be4a9d2011-05-16 15:44:09 -070081
Chris Masone3bd3c8c2011-06-13 08:20:26 -070082class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070083 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070084 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020085 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080086 device_info_(new NiceMock<MockDeviceInfo>(
87 control_interface(),
88 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080089 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080090 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080091 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070092 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080093 wifi_provider_(new NiceMock<MockWiFiProvider>()),
94 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
95 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070096 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
97 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080098 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070099 manager(),
100 "null0",
101 "addr0",
102 0));
103 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
104 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800105 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700106 manager(),
107 "null1",
108 "addr1",
109 1));
110 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
111 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800112 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700113 manager(),
114 "null2",
115 "addr2",
116 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800117 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
118 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800119 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800120 manager(),
121 "null3",
122 "addr3",
123 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700124 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800125 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800126
127 // Replace the manager's adaptor with a quieter one, and one
128 // we can do EXPECT*() against. Passes ownership.
129 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800130
Paul Stewart35eff132013-04-12 12:08:40 -0700131 // Replace the manager's Ethernet EAP provider with our mock.
132 // Passes ownership.
133 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
134
Paul Stewart3c504012013-01-17 17:49:58 -0800135 // Replace the manager's WiFi provider with our mock. Passes
136 // ownership.
137 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800138
Paul Stewartb87d22b2013-07-29 11:11:37 -0700139 // Update the manager's map from technology to provider.
140 manager()->UpdateProviderMapping();
141
Christopher Wiley1057cd72013-02-28 15:21:29 -0800142 // Replace the manager's crypto util proxy with our mock. Passes
143 // ownership.
144 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Paul Stewart9dd253e2013-04-22 08:32:59 -0700145
146 // Reset service serial number so service sorting by unique_name()
147 // (and by extension, sorting by order of creation) is predictable.
148 Service::serial_number_ = 10000;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700149 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700150 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700151
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100152 void SetMetrics(Metrics *metrics) {
153 manager()->set_metrics(metrics);
154 }
155
Paul Stewartfdd16072011-09-16 12:41:35 -0700156 bool IsDeviceRegistered(const DeviceRefPtr &device,
157 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700158 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700159 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700160 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700161 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700162 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700163
Paul Stewarta849a3d2011-11-03 05:54:09 -0700164 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
165 manager->profiles_.push_back(profile);
166 }
167
Paul Stewart63864b62012-11-07 15:10:55 -0800168 void SetRunning(bool running) {
169 manager()->running_ = running;
170 }
171
Paul Stewart75225512012-01-26 22:51:33 -0800172 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
173 return manager->ephemeral_profile_;
174 }
175
Paul Stewart307c2502013-03-23 12:32:10 -0700176 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
177 return manager->profiles_;
178 }
179
Chris Masone6515aab2011-10-12 16:19:09 -0700180 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
181 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700182 FilePath final_path(storage_path());
183 final_path = final_path.Append("test.profile");
184 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
185 storage->set_path(final_path);
186 if (!storage->Open())
187 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800188 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800189 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800190 manager,
191 id,
192 "",
193 false));
194 profile->set_storage(storage.release()); // Passes ownership of "storage".
195 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700196 }
197
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700198 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
199 const string &profile_identifier,
200 const string &service_name) {
201 GLib glib;
202 KeyFileStore store(&glib);
203 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
204 return store.Open() &&
205 store.SetString(service_name, "rather", "irrelevant") &&
206 store.Close();
207 }
208
209 Error::Type TestCreateProfile(Manager *manager, const string &name) {
210 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800211 string path;
212 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700213 return error.type();
214 }
215
216 Error::Type TestPopAnyProfile(Manager *manager) {
217 Error error;
218 manager->PopAnyProfile(&error);
219 return error.type();
220 }
221
Paul Stewart307c2502013-03-23 12:32:10 -0700222 Error::Type TestPopAllUserProfiles(Manager *manager) {
223 Error error;
224 manager->PopAllUserProfiles(&error);
225 return error.type();
226 }
227
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700228 Error::Type TestPopProfile(Manager *manager, const string &name) {
229 Error error;
230 manager->PopProfile(name, &error);
231 return error.type();
232 }
233
234 Error::Type TestPushProfile(Manager *manager, const string &name) {
235 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800236 string path;
237 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700238 return error.type();
239 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000240
Paul Stewartf3eced92013-04-17 12:18:22 -0700241 Error::Type TestInsertUserProfile(Manager *manager,
242 const string &name,
243 const string &user_hash) {
244 Error error;
245 string path;
246 manager->InsertUserProfile(name, user_hash, &path, &error);
247 return error.type();
248 }
249
Paul Stewartd2e1c362013-03-03 19:06:07 -0800250 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
251 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700252 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800253 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800254 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200255 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700256 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800257 return profile;
258 }
259
260 void AddMockProfileToManager(Manager *manager) {
261 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700262 }
263
Paul Stewartdfa46052012-06-26 09:44:14 -0700264 void CompleteServiceSort() {
265 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
266 dispatcher()->DispatchPendingEvents();
267 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
268 }
269
Paul Stewart49739c02012-08-08 17:24:03 -0700270 RpcIdentifier GetDefaultServiceRpcIdentifier() {
271 return manager()->GetDefaultServiceRpcIdentifier(NULL);
272 }
273
Paul Stewart4d5efb72012-09-17 12:24:34 -0700274 void SetResolver(Resolver *resolver) {
275 manager()->resolver_ = resolver;
276 }
277
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700278 bool SetIgnoredDNSSearchPaths(const string &search_paths, Error *error) {
279 return manager()->SetIgnoredDNSSearchPaths(search_paths, error);
280 }
281
282 bool SetCheckPortalList(const string &check_portal_list, Error *error) {
283 return manager()->SetCheckPortalList(check_portal_list, error);
Paul Stewart4d5efb72012-09-17 12:24:34 -0700284 }
285
286 const string &GetIgnoredDNSSearchPaths() {
287 return manager()->props_.ignored_dns_search_paths;
288 }
289
Paul Stewartd2e1c362013-03-03 19:06:07 -0800290 WiFiServiceRefPtr ReleaseTempMockService() {
291 // Take a reference to hold during this function.
292 WiFiServiceRefPtr temp_service = temp_mock_service_;
293 temp_mock_service_ = NULL;
294 return temp_service;
295 }
296
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700297 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000298 typedef scoped_refptr<MockService> MockServiceRefPtr;
299
Darin Petkova5e07ef2012-07-09 14:27:57 +0200300 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
301 public:
302 ServiceWatcher() {}
303 virtual ~ServiceWatcher() {}
304
305 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
306
307 private:
308 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
309 };
310
Darin Petkovca621542012-07-25 14:25:56 +0200311 class TestProxyFactory : public ProxyFactory {
312 public:
313 TestProxyFactory() {}
314
315 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
316 PowerManagerProxyDelegate */*delegate*/) {
317 return NULL;
318 }
319
320 private:
321 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
322 };
323
Darin Petkov3ec55342012-09-28 14:04:44 +0200324 class TerminationActionTest :
325 public base::SupportsWeakPtr<TerminationActionTest> {
326 public:
327 static const char kActionName[];
328
329 TerminationActionTest() : manager_(NULL) {}
330 virtual ~TerminationActionTest() {}
331
332 MOCK_METHOD1(Done, void(const Error &error));
333
334 void Action() {
335 manager_->TerminationActionComplete("action");
336 }
337
338 void set_manager(Manager *manager) { manager_ = manager; }
339
340 private:
341 Manager *manager_;
342 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
343 };
344
Christopher Wiley1057cd72013-02-28 15:21:29 -0800345 class DestinationVerificationTest :
346 public base::SupportsWeakPtr<DestinationVerificationTest> {
347 public:
348 DestinationVerificationTest() {}
349 virtual ~DestinationVerificationTest() {}
350
351 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
352 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
353 const string &value));
354 private:
355 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
356 };
357
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700358 class DisableTechnologyReplyHandler :
359 public base::SupportsWeakPtr<DisableTechnologyReplyHandler> {
360 public:
361 DisableTechnologyReplyHandler() {}
362 virtual ~DisableTechnologyReplyHandler() {}
363
364 MOCK_METHOD1(ReportResult, void(const Error &));
365
366 private:
367 DISALLOW_COPY_AND_ASSIGN(DisableTechnologyReplyHandler);
368 };
369
Darin Petkovca621542012-07-25 14:25:56 +0200370 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
371 power_manager_->power_state_ = state;
372 }
373
374 void SetPowerManager() {
375 manager()->set_power_manager(power_manager_.release());
376 }
377
Darin Petkov3ec55342012-09-28 14:04:44 +0200378 HookTable *GetTerminationActions() {
379 return &manager()->termination_actions_;
380 }
381
Darin Petkovca621542012-07-25 14:25:56 +0200382 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
383 manager()->OnPowerStateChanged(state);
384 }
385
Daniel Erat0818cca2012-12-14 10:16:21 -0800386 void OnSuspendImminent(int suspend_id) {
387 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200388 }
389
Daniel Erat0818cca2012-12-14 10:16:21 -0800390 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
391 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200392 }
393
Paul Stewartbfb82552012-10-24 16:48:48 -0700394 vector<string> EnumerateAvailableServices() {
395 return manager()->EnumerateAvailableServices(NULL);
396 }
397
398 vector<string> EnumerateWatchedServices() {
399 return manager()->EnumerateWatchedServices(NULL);
400 }
401
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000402 MockServiceRefPtr MakeAutoConnectableService() {
403 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
404 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800405 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000406 manager());
407 service->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700408 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000409 return service;
410 }
411
Paul Stewart35eff132013-04-12 12:08:40 -0700412 void SetEapProviderService(const ServiceRefPtr &service) {
413 ethernet_eap_provider_->set_service(service);
414 }
415
Darin Petkovca621542012-07-25 14:25:56 +0200416 TestProxyFactory proxy_factory_;
417 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700418 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800419 scoped_ptr<MockDeviceInfo> device_info_;
420
Paul Stewartd2e1c362013-03-03 19:06:07 -0800421 // This service is held for the manager, and given ownership in a mock
422 // function. This ensures that when the Manager takes ownership, there
423 // is only one reference left.
424 scoped_refptr<MockWiFiService> temp_mock_service_;
425
Paul Stewart3c504012013-01-17 17:49:58 -0800426 // These pointers are owned by the manager, and only tracked here for
427 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800428 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700429 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800430 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800431 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700432};
433
Darin Petkov3ec55342012-09-28 14:04:44 +0200434const char ManagerTest::TerminationActionTest::kActionName[] = "action";
435
Paul Stewart22aa71b2011-09-16 12:15:11 -0700436bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700437 if (!manager()->sort_services_task_.IsCancelled()) {
438 manager()->SortServicesTask();
439 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700440 return (svc0.get() == manager()->services_[0].get() &&
441 svc1.get() == manager()->services_[1].get());
442}
443
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700444void SetErrorPermissionDenied(Error *error) {
445 error->Populate(Error::kPermissionDenied);
446}
447
Arman Uguray2f352e62013-08-28 19:12:53 -0700448void SetErrorSuccess(Error *error) {
449 error->Reset();
450}
451
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700452TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700453 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
454 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700455}
456
Chris Masone9be4a9d2011-05-16 15:44:09 -0700457TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700458 ON_CALL(*mock_devices_[0].get(), technology())
459 .WillByDefault(Return(Technology::kEthernet));
460 ON_CALL(*mock_devices_[1].get(), technology())
461 .WillByDefault(Return(Technology::kWifi));
462 ON_CALL(*mock_devices_[2].get(), technology())
463 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700464
Paul Stewart22aa71b2011-09-16 12:15:11 -0700465 manager()->RegisterDevice(mock_devices_[0]);
466 manager()->RegisterDevice(mock_devices_[1]);
467 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700468
Paul Stewart22aa71b2011-09-16 12:15:11 -0700469 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
470 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
471 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700472}
473
Paul Stewarta41e38d2011-11-11 07:47:29 -0800474TEST_F(ManagerTest, DeviceRegistrationAndStart) {
475 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500476 mock_devices_[0]->enabled_persistent_ = true;
477 mock_devices_[1]->enabled_persistent_ = false;
478 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800479 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500480 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800481 .Times(0);
482 manager()->RegisterDevice(mock_devices_[0]);
483 manager()->RegisterDevice(mock_devices_[1]);
484}
485
486TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800487 MockProfile *profile =
488 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800489 DeviceRefPtr device_ref(mock_devices_[0].get());
490 AdoptProfile(manager(), profile); // Passes ownership.
491 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200492 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800493 manager()->RegisterDevice(mock_devices_[0]);
494}
495
Chris Masone9be4a9d2011-05-16 15:44:09 -0700496TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700497 ON_CALL(*mock_devices_[0].get(), technology())
498 .WillByDefault(Return(Technology::kEthernet));
499 ON_CALL(*mock_devices_[1].get(), technology())
500 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700501
Gaurav Shah435de2c2011-11-17 19:01:07 -0800502 manager()->RegisterDevice(mock_devices_[0]);
503 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700504
Paul Stewart22aa71b2011-09-16 12:15:11 -0700505 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
506 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700507
Thieu Le5133b712013-02-19 14:47:21 -0800508 MockProfile *profile =
509 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700510 AdoptProfile(manager(), profile); // Passes ownership.
511
Eric Shienbrood9a245532012-03-07 14:20:39 -0500512 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700513 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800514 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700515 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700516
Eric Shienbrood9a245532012-03-07 14:20:39 -0500517 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700518 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800519 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700520 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700521}
522
523TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700524 // It's much easier and safer to use a real GLib for this test.
525 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700526 Manager manager(control_interface(),
527 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800528 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700529 &glib,
530 run_path(),
531 storage_path(),
532 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700533 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
534 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700535 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700536
Chris Masone9be4a9d2011-05-16 15:44:09 -0700537 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700538 new NiceMock<MockService>(control_interface(),
539 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800540 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700541 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700542 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700543 new NiceMock<MockService>(control_interface(),
544 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800545 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700546 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700547
Darin Petkov457728b2013-01-09 09:49:08 +0100548 string service1_name(mock_service->unique_name());
549 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700550
551 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
552 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700553 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700554 .WillRepeatedly(Return(service2_name));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700555 // TODO(quiche): make this EXPECT_CALL work (crbug.com/203247)
Chris Masone9d779932011-08-25 16:33:41 -0700556 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700557 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700558
Chris Masone9d779932011-08-25 16:33:41 -0700559 manager.RegisterService(mock_service);
560 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700561
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800562 Error error;
563 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700564 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700565 EXPECT_EQ(2, ids.size());
566 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
567 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700568
Chris Masone9d779932011-08-25 16:33:41 -0700569 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
570 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
571
572 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700573}
574
Chris Masone6515aab2011-10-12 16:19:09 -0700575TEST_F(ManagerTest, RegisterKnownService) {
576 // It's much easier and safer to use a real GLib for this test.
577 GLib glib;
578 Manager manager(control_interface(),
579 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800580 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700581 &glib,
582 run_path(),
583 storage_path(),
584 string());
585 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
586 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700587 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700588 {
589 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
590 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800591 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700592 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700593 ASSERT_TRUE(profile->AdoptService(service1));
594 ASSERT_TRUE(profile->ContainsService(service1));
595 } // Force destruction of service1.
596
597 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
598 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800599 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700600 &manager));
601 manager.RegisterService(service2);
602 EXPECT_EQ(service2->profile().get(), profile.get());
603 manager.Stop();
604}
605
606TEST_F(ManagerTest, RegisterUnknownService) {
607 // It's much easier and safer to use a real GLib for this test.
608 GLib glib;
609 Manager manager(control_interface(),
610 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800611 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700612 &glib,
613 run_path(),
614 storage_path(),
615 string());
616 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
617 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700618 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700619 {
620 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
621 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800622 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700623 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700624 ASSERT_TRUE(profile->AdoptService(service1));
625 ASSERT_TRUE(profile->ContainsService(service1));
626 } // Force destruction of service1.
627 scoped_refptr<MockService> mock_service2(
628 new NiceMock<MockService>(control_interface(),
629 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800630 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700631 &manager));
632 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100633 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700634 manager.RegisterService(mock_service2);
635 EXPECT_NE(mock_service2->profile().get(), profile.get());
636 manager.Stop();
637}
638
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000639TEST_F(ManagerTest, DeregisterUnregisteredService) {
640 // WiFi assumes that it can deregister a service that is not
641 // registered. (E.g. a hidden service can be deregistered when it
642 // loses its last endpoint, and again when WiFi is Stop()-ed.)
643 //
644 // So test that doing so doesn't cause a crash.
645 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
646 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800647 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000648 manager());
649 manager()->DeregisterService(service);
650}
651
Chris Masonea8a2c252011-06-27 22:16:30 -0700652TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700653 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700654 map<string, ::DBus::Variant> props;
655 Error error(Error::kInvalidProperty, "");
656 {
657 ::DBus::Error dbus_error;
658 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700659 manager()->mutable_store()->SetStringProperty(
660 flimflam::kCheckPortalListProperty,
661 expected,
662 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700663 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700664 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
665 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
666 expected);
667 }
668 {
669 ::DBus::Error dbus_error;
670 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700671 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
672 expected,
673 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700674 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700675 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
676 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
677 expected);
678 }
679}
680
Chris Masone3c3f6a12011-07-01 10:01:41 -0700681TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700682 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800683 manager()->RegisterDevice(mock_devices_[0]);
684 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700685 {
686 map<string, ::DBus::Variant> props;
687 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700688 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700689 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700690 vector < ::DBus::Path> devices =
691 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700692 EXPECT_EQ(2, devices.size());
693 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700694}
695
mukesh agrawal2366eed2012-03-20 18:21:50 -0700696TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700697 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700698 map<string, ::DBus::Variant> props;
699 ::DBus::Error dbus_error;
700 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
701 map<string, ::DBus::Variant>::const_iterator prop =
702 props.find(flimflam::kServicesProperty);
703 ASSERT_FALSE(prop == props.end());
704 const ::DBus::Variant &variant = prop->second;
705 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
706}
707
Chris Masone6791a432011-07-12 13:23:19 -0700708TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700709 Manager manager(control_interface(),
710 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800711 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700712 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700713 run_path(),
714 storage_path(),
715 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700716 scoped_refptr<MockService> s2(new MockService(control_interface(),
717 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800718 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700719 &manager));
720 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700721 {
Chris Masone6515aab2011-10-12 16:19:09 -0700722 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700723 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800724 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700725 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700726 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700727 .WillRepeatedly(Return(true));
728 EXPECT_CALL(*storage, Flush())
729 .Times(AnyNumber())
730 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700731 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700732 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700733 }
Chris Masone6515aab2011-10-12 16:19:09 -0700734 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800735 ProfileRefPtr profile(
736 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700737 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700738
Chris Masone6515aab2011-10-12 16:19:09 -0700739 // Now, move the Service |s2| to another profile.
740 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
741 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700742
743 // Force destruction of the original Profile, to ensure that the Service
744 // is kept alive and populated with data.
745 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700746 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700747 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700748}
749
Paul Stewart7f61e522012-03-22 11:13:45 -0700750TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
751 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800752 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700753 const string kProfileName("profile0");
754 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
755 .WillRepeatedly(Return(kProfileName));
756 AdoptProfile(manager(), mock_profile);
757
758 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
759 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
760 EXPECT_EQ(mock_profile.get(), profile.get());
761}
762
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800763TEST_F(ManagerTest, SetProfileForService) {
764 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800765 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800766 string profile_name0("profile0");
767 EXPECT_CALL(*profile0, GetRpcIdentifier())
768 .WillRepeatedly(Return(profile_name0));
769 AdoptProfile(manager(), profile0);
770 scoped_refptr<MockService> service(new MockService(control_interface(),
771 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800772 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800773 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700774 EXPECT_FALSE(manager()->HasService(service));
775 {
776 Error error;
777 EXPECT_CALL(*profile0, AdoptService(_))
778 .WillOnce(Return(true));
779 // Expect that setting the profile of a service that does not already
780 // have one assigned does not cause a crash.
781 manager()->SetProfileForService(service, "profile0", &error);
782 EXPECT_TRUE(error.IsSuccess());
783 }
784
785 // The service should be registered as a side-effect of the profile being
786 // set for this service.
787 EXPECT_TRUE(manager()->HasService(service));
788
789 // Since we have mocked Profile::AdoptServie() above, the service's
790 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800791 service->set_profile(profile0);
792
793 {
794 Error error;
795 manager()->SetProfileForService(service, "foo", &error);
796 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700797 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800798 }
799
800 {
801 Error error;
802 manager()->SetProfileForService(service, profile_name0, &error);
803 EXPECT_EQ(Error::kInvalidArguments, error.type());
804 EXPECT_EQ("Service is already connected to this profile", error.message());
805 }
806
807 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800808 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800809 string profile_name1("profile1");
810 EXPECT_CALL(*profile1, GetRpcIdentifier())
811 .WillRepeatedly(Return(profile_name1));
812 AdoptProfile(manager(), profile1);
813
814 {
815 Error error;
816 EXPECT_CALL(*profile1, AdoptService(_))
817 .WillOnce(Return(true));
818 EXPECT_CALL(*profile0, AbandonService(_))
819 .WillOnce(Return(true));
820 manager()->SetProfileForService(service, profile_name1, &error);
821 EXPECT_TRUE(error.IsSuccess());
822 }
823}
824
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700825TEST_F(ManagerTest, CreateProfile) {
826 // It's much easier to use real Glib here since we want the storage
827 // side-effects.
828 GLib glib;
829 ScopedTempDir temp_dir;
830 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
831
832 Manager manager(control_interface(),
833 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800834 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700835 &glib,
836 run_path(),
837 storage_path(),
838 temp_dir.path().value());
839
840 // Invalid name should be rejected.
841 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
842
Paul Stewartd0a3b812012-03-28 22:48:22 -0700843 // A profile with invalid characters in it should similarly be rejected.
844 EXPECT_EQ(Error::kInvalidArguments,
845 TestCreateProfile(&manager, "valid_profile"));
846
847 // We should be able to create a machine profile.
848 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700849
Gary Morainb672d352012-04-25 09:19:06 -0700850 // We should succeed in creating a valid user profile. Verify the returned
851 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700852 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700853 {
854 Error error;
855 string path;
856 manager.CreateProfile(kProfile, &path, &error);
857 EXPECT_EQ(Error::kSuccess, error.type());
858 EXPECT_EQ("/profile_rpc", path);
859 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700860
861 // We should fail in creating it a second time (already exists).
862 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
863}
864
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700865// We receive PopProfile when a user logs out, and it should always trigger a
866// MemoryLog Clear() call.
867TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
868 GLib glib;
869 ScopedTempDir temp_dir;
870 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
871 Manager manager(control_interface(),
872 dispatcher(),
873 metrics(),
874 &glib,
875 run_path(),
876 storage_path(),
877 temp_dir.path().value());
878 const char kProfile0[] = "~user/profile0";
879 const char kPurgedMessage[] = "This message should be purged";
880 // Create a profile and push it on the stack, leave one uncreated
881 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
882 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
883
884 // Popping a profile which isn't on top should still clear the log.
885 LOG(INFO) << kPurgedMessage;
886 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
887 kPurgedMessage));
888 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
889 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
890 kPurgedMessage));
891
892 // Popping an invalid profile name should do the same thing.
893 LOG(INFO) << kPurgedMessage;
894 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
895 kPurgedMessage));
896 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
897 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
898 kPurgedMessage));
899
900 // Successful pops also purge the message log.
901 LOG(INFO) << kPurgedMessage;
902 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
903 kPurgedMessage));
904 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
905 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
906 kPurgedMessage));
907}
908
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700909TEST_F(ManagerTest, PushPopProfile) {
910 // It's much easier to use real Glib in creating a Manager for this
911 // test here since we want the storage side-effects.
912 GLib glib;
913 ScopedTempDir temp_dir;
914 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
915 Manager manager(control_interface(),
916 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800917 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700918 &glib,
919 run_path(),
920 storage_path(),
921 temp_dir.path().value());
922
923 // Pushing an invalid profile should fail.
924 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
925
Paul Stewartd0a3b812012-03-28 22:48:22 -0700926 // Pushing a default profile that does not exist should fail.
927 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700928
929 const char kProfile0[] = "~user/profile0";
930 const char kProfile1[] = "~user/profile1";
931
932 // Create a couple of profiles.
933 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
934 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
935
936 // Push these profiles on the stack.
937 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
938 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
939
940 // Pushing a profile a second time should fail.
941 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
942 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
943
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800944 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700945 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800946 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700947
948 // Make sure a profile name that doesn't exist fails.
949 const char kProfile2Id[] = "profile2";
950 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
951 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
952
953 // Create a new service, with a specific storage name.
954 scoped_refptr<MockService> service(
955 new NiceMock<MockService>(control_interface(),
956 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800957 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700958 &manager));
959 const char kServiceName[] = "service_storage_name";
960 EXPECT_CALL(*service.get(), GetStorageIdentifier())
961 .WillRepeatedly(Return(kServiceName));
962 EXPECT_CALL(*service.get(), Load(_))
963 .WillRepeatedly(Return(true));
964
965 // Add this service to the manager -- it should end up in the ephemeral
966 // profile.
967 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800968 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700969
970 // Create storage for a profile that contains the service storage name.
971 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
972 kServiceName));
973
974 // When we push the profile, the service should move away from the
975 // ephemeral profile to this new profile since it has an entry for
976 // this service.
977 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800978 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700979 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
980
981 // Insert another profile that should supersede ownership of the service.
982 const char kProfile3Id[] = "profile3";
983 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
984 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
985 kServiceName));
986 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
987 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
988
989 // Popping an invalid profile name should fail.
990 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
991
992 // Popping an profile that is not at the top of the stack should fail.
993 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
994
995 // Popping the top profile should succeed.
996 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
997
998 // Moreover the service should have switched profiles to profile 2.
999 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
1000
1001 // Popping the top profile should succeed.
1002 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1003
1004 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -08001005 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001006
1007 // Pop the remaining two services off the stack.
1008 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1009 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1010
1011 // Next pop should fail with "stack is empty".
1012 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -07001013
1014 const char kMachineProfile0[] = "machineprofile0";
1015 const char kMachineProfile1[] = "machineprofile1";
1016 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
1017 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
1018
1019 // Should be able to push a machine profile.
1020 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
1021
1022 // Should be able to push a user profile atop a machine profile.
1023 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1024
1025 // Pushing a system-wide profile on top of a user profile should fail.
1026 EXPECT_EQ(Error::kInvalidArguments,
1027 TestPushProfile(&manager, kMachineProfile1));
1028
1029 // However if we pop the user profile, we should be able stack another
1030 // machine profile on.
1031 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1032 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001033
1034 // Add two user profiles to the top of the stack.
1035 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1036 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
1037 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
1038 EXPECT_EQ(4, profiles.size());
1039
1040 // PopAllUserProfiles should remove both user profiles, leaving the two
1041 // machine profiles.
1042 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1043 EXPECT_EQ(2, profiles.size());
1044 EXPECT_TRUE(profiles[0]->GetUser().empty());
1045 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001046
1047 // Use InsertUserProfile() instead. Although a machine profile is valid
1048 // in this state, it cannot be added via InsertUserProfile.
1049 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1050 EXPECT_EQ(Error::kInvalidArguments,
1051 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1052 const char kUserHash0[] = "userhash0";
1053 const char kUserHash1[] = "userhash1";
1054 EXPECT_EQ(Error::kSuccess,
1055 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1056 EXPECT_EQ(Error::kSuccess,
1057 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1058 EXPECT_EQ(3, profiles.size());
1059 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1060 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001061}
1062
Paul Stewarte73d05c2012-03-29 16:26:05 -07001063TEST_F(ManagerTest, RemoveProfile) {
1064 // It's much easier to use real Glib in creating a Manager for this
1065 // test here since we want the storage side-effects.
1066 GLib glib;
1067 ScopedTempDir temp_dir;
1068 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1069 Manager manager(control_interface(),
1070 dispatcher(),
1071 metrics(),
1072 &glib,
1073 run_path(),
1074 storage_path(),
1075 temp_dir.path().value());
1076
1077 const char kProfile0[] = "profile0";
1078 FilePath profile_path(
1079 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1080
1081 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1082 ASSERT_TRUE(file_util::PathExists(profile_path));
1083
1084 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1085
1086 // Remove should fail since the profile is still on the stack.
1087 {
1088 Error error;
1089 manager.RemoveProfile(kProfile0, &error);
1090 EXPECT_EQ(Error::kInvalidArguments, error.type());
1091 }
1092
1093 // Profile path should still exist.
1094 EXPECT_TRUE(file_util::PathExists(profile_path));
1095
1096 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1097
1098 // This should succeed now that the profile is off the stack.
1099 {
1100 Error error;
1101 manager.RemoveProfile(kProfile0, &error);
1102 EXPECT_EQ(Error::kSuccess, error.type());
1103 }
1104
1105 // Profile path should no longer exist.
1106 EXPECT_FALSE(file_util::PathExists(profile_path));
1107
1108 // Another remove succeeds, due to a foible in file_util::Delete --
1109 // it is not an error to delete a file that does not exist.
1110 {
1111 Error error;
1112 manager.RemoveProfile(kProfile0, &error);
1113 EXPECT_EQ(Error::kSuccess, error.type());
1114 }
1115
1116 // Let's create an error case that will "work". Create a non-empty
1117 // directory in the place of the profile pathname.
1118 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1119 {
1120 Error error;
1121 manager.RemoveProfile(kProfile0, &error);
1122 EXPECT_EQ(Error::kOperationFailed, error.type());
1123 }
1124}
1125
Paul Stewartd3d03882013-08-29 15:43:42 -07001126TEST_F(ManagerTest, RemoveService) {
1127 MockServiceRefPtr mock_service(
1128 new NiceMock<MockService>(control_interface(),
1129 dispatcher(),
1130 metrics(),
1131 manager()));
1132
1133 // Used in expectations which cannot accept a mock refptr.
1134 const ServiceRefPtr &service = mock_service;
1135
1136 manager()->RegisterService(service);
1137 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1138
1139 scoped_refptr<MockProfile> profile(
1140 new StrictMock<MockProfile>(
1141 control_interface(), metrics(), manager(), ""));
1142 AdoptProfile(manager(), profile);
1143
1144 // If service is ephemeral, it should be unloaded and left ephemeral.
1145 EXPECT_CALL(*profile, AbandonService(service)).Times(0);
1146 EXPECT_CALL(*profile, ConfigureService(service)).Times(0);
1147 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(false));
1148 manager()->RemoveService(service);
1149 Mock::VerifyAndClearExpectations(mock_service);
1150 Mock::VerifyAndClearExpectations(profile);
1151 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1152 EXPECT_TRUE(manager()->HasService(service)); // Since Unload() was false.
1153
1154 // If service is not ephemeral and the Manager finds a profile to assign
1155 // the service to, the service should be re-parented. Note that since we
1156 // are using a MockProfile, ConfigureService() never actually changes the
1157 // Service's profile.
1158 service->set_profile(profile);
1159 EXPECT_CALL(*profile, AbandonService(service));
1160 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(true));
1161 EXPECT_CALL(*mock_service, Unload()).Times(0);
1162 manager()->RemoveService(service);
1163 Mock::VerifyAndClearExpectations(mock_service);
1164 Mock::VerifyAndClearExpectations(profile);
1165 EXPECT_TRUE(manager()->HasService(service));
1166 EXPECT_EQ(profile.get(), service->profile().get());
1167
1168 // If service becomes ephemeral since there is no profile to support it,
1169 // it should be unloaded.
1170 EXPECT_CALL(*profile, AbandonService(service));
1171 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(false));
1172 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(true));
1173 manager()->RemoveService(service);
1174 EXPECT_FALSE(manager()->HasService(service));
1175}
1176
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001177TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1178 // It's much easier to use real Glib in creating a Manager for this
1179 // test here since we want the storage side-effects.
1180 GLib glib;
1181 ScopedTempDir temp_dir;
1182 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1183 Manager manager(control_interface(),
1184 dispatcher(),
1185 metrics(),
1186 &glib,
1187 run_path(),
1188 storage_path(),
1189 temp_dir.path().value());
1190
1191 const char kProfile0[] = "profile0";
1192 FilePath profile_path(
1193 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1194
1195 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1196 ASSERT_TRUE(file_util::PathExists(profile_path));
1197 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1198
1199 // Ensure that even if the backing filestore is removed, we still can't
1200 // create a profile twice.
1201 ASSERT_TRUE(file_util::Delete(profile_path, false));
1202 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1203}
1204
Paul Stewart75225512012-01-26 22:51:33 -08001205// Use this matcher instead of passing RefPtrs directly into the arguments
1206// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1207// system teardown.
1208MATCHER_P(IsRefPtrTo, ref_address, "") {
1209 return arg.get() == ref_address;
1210}
1211
1212TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1213 MockServiceRefPtr s_not_in_profile(
1214 new NiceMock<MockService>(control_interface(),
1215 dispatcher(),
1216 metrics(),
1217 manager()));
1218 MockServiceRefPtr s_not_in_group(
1219 new NiceMock<MockService>(control_interface(),
1220 dispatcher(),
1221 metrics(),
1222 manager()));
1223 MockServiceRefPtr s_configure_fail(
1224 new NiceMock<MockService>(control_interface(),
1225 dispatcher(),
1226 metrics(),
1227 manager()));
1228 MockServiceRefPtr s_configure_succeed(
1229 new NiceMock<MockService>(control_interface(),
1230 dispatcher(),
1231 metrics(),
1232 manager()));
1233
1234 string entry_name("entry_name");
1235 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1236 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1237 .WillRepeatedly(Return("not_entry_name"));
1238 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1239 .WillRepeatedly(Return(entry_name));
1240 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1241 .WillRepeatedly(Return(entry_name));
1242
1243 manager()->RegisterService(s_not_in_profile);
1244 manager()->RegisterService(s_not_in_group);
1245 manager()->RegisterService(s_configure_fail);
1246 manager()->RegisterService(s_configure_succeed);
1247
1248 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001249 new StrictMock<MockProfile>(
1250 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001251 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001252 new StrictMock<MockProfile>(
1253 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001254
1255 s_not_in_group->set_profile(profile1);
1256 s_configure_fail->set_profile(profile1);
1257 s_configure_succeed->set_profile(profile1);
1258
1259 AdoptProfile(manager(), profile0);
1260 AdoptProfile(manager(), profile1);
1261
1262 // No services are a member of this profile.
1263 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1264
1265 // No services that are members of this profile have this entry name.
1266 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1267
1268 // Only services that are members of the profile and group will be abandoned.
1269 EXPECT_CALL(*profile1.get(),
1270 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1271 EXPECT_CALL(*profile1.get(),
1272 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1273 EXPECT_CALL(*profile1.get(),
1274 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1275 .WillOnce(Return(true));
1276 EXPECT_CALL(*profile1.get(),
1277 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1278 .WillOnce(Return(true));
1279
1280 // Never allow services to re-join profile1.
1281 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1282 .WillRepeatedly(Return(false));
1283
1284 // Only allow one of the members of the profile and group to successfully
1285 // join profile0.
1286 EXPECT_CALL(*profile0.get(),
1287 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1288 EXPECT_CALL(*profile0.get(),
1289 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1290 EXPECT_CALL(*profile0.get(),
1291 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1292 .WillOnce(Return(false));
1293 EXPECT_CALL(*profile0.get(),
1294 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1295 .WillOnce(Return(true));
1296
1297 // Expect the failed-to-configure service to have Unload() called on it.
1298 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1299 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1300 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1301 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1302
1303 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1304
1305 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1306 EXPECT_EQ(profile1, s_not_in_group->profile());
1307 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1308
1309 // Since we are using a MockProfile, the profile does not actually change,
1310 // since ConfigureService was not actually called on the service.
1311 EXPECT_EQ(profile1, s_configure_succeed->profile());
1312}
1313
Paul Stewart65512e12012-03-26 18:01:08 -07001314TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1315 MockServiceRefPtr s_will_remove0(
1316 new NiceMock<MockService>(control_interface(),
1317 dispatcher(),
1318 metrics(),
1319 manager()));
1320 MockServiceRefPtr s_will_remove1(
1321 new NiceMock<MockService>(control_interface(),
1322 dispatcher(),
1323 metrics(),
1324 manager()));
1325 MockServiceRefPtr s_will_not_remove0(
1326 new NiceMock<MockService>(control_interface(),
1327 dispatcher(),
1328 metrics(),
1329 manager()));
1330 MockServiceRefPtr s_will_not_remove1(
1331 new NiceMock<MockService>(control_interface(),
1332 dispatcher(),
1333 metrics(),
1334 manager()));
1335
1336 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1337 .Times(4); // Once for each registration.
1338
1339 string entry_name("entry_name");
1340 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1341 .WillRepeatedly(Return(entry_name));
1342 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1343 .WillRepeatedly(Return(entry_name));
1344 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1345 .WillRepeatedly(Return(entry_name));
1346 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1347 .WillRepeatedly(Return(entry_name));
1348
1349 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001350 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001351 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001352 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001353 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001354 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001355 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001356 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001357
1358 // One for each service added above.
1359 ASSERT_EQ(4, manager()->services_.size());
1360
1361 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001362 new StrictMock<MockProfile>(
1363 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001364
1365 s_will_remove0->set_profile(profile);
1366 s_will_remove1->set_profile(profile);
1367 s_will_not_remove0->set_profile(profile);
1368 s_will_not_remove1->set_profile(profile);
1369
1370 AdoptProfile(manager(), profile);
1371
1372 // Deny any of the services re-entry to the profile.
1373 EXPECT_CALL(*profile, ConfigureService(_))
1374 .WillRepeatedly(Return(false));
1375
1376 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1377 .WillOnce(Return(true));
1378 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1379 .WillOnce(Return(true));
1380 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1381 .WillOnce(Return(true));
1382 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1383 .WillOnce(Return(true));
1384
1385 EXPECT_CALL(*s_will_remove0, Unload())
1386 .WillOnce(Return(true));
1387 EXPECT_CALL(*s_will_remove1, Unload())
1388 .WillOnce(Return(true));
1389 EXPECT_CALL(*s_will_not_remove0, Unload())
1390 .WillOnce(Return(false));
1391 EXPECT_CALL(*s_will_not_remove1, Unload())
1392 .WillOnce(Return(false));
1393
1394
1395 // This will cause all the profiles to be unloaded.
1396 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1397
1398 // 2 of the 4 services added above should have been unregistered and
1399 // removed, leaving 2.
1400 EXPECT_EQ(2, manager()->services_.size());
1401 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1402 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1403}
1404
1405TEST_F(ManagerTest, PopProfileWithUnload) {
1406 MockServiceRefPtr s_will_remove0(
1407 new NiceMock<MockService>(control_interface(),
1408 dispatcher(),
1409 metrics(),
1410 manager()));
1411 MockServiceRefPtr s_will_remove1(
1412 new NiceMock<MockService>(control_interface(),
1413 dispatcher(),
1414 metrics(),
1415 manager()));
1416 MockServiceRefPtr s_will_not_remove0(
1417 new NiceMock<MockService>(control_interface(),
1418 dispatcher(),
1419 metrics(),
1420 manager()));
1421 MockServiceRefPtr s_will_not_remove1(
1422 new NiceMock<MockService>(control_interface(),
1423 dispatcher(),
1424 metrics(),
1425 manager()));
1426
1427 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1428 .Times(5); // Once for each registration, and one after profile pop.
1429
1430 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001431 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001432 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001433 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001434 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001435 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001436 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001437 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001438
1439 // One for each service added above.
1440 ASSERT_EQ(4, manager()->services_.size());
1441
1442 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001443 new StrictMock<MockProfile>(
1444 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001445 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001446 new StrictMock<MockProfile>(
1447 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001448
1449 s_will_remove0->set_profile(profile1);
1450 s_will_remove1->set_profile(profile1);
1451 s_will_not_remove0->set_profile(profile1);
1452 s_will_not_remove1->set_profile(profile1);
1453
1454 AdoptProfile(manager(), profile0);
1455 AdoptProfile(manager(), profile1);
1456
1457 // Deny any of the services entry to profile0, so they will all be unloaded.
1458 EXPECT_CALL(*profile0, ConfigureService(_))
1459 .WillRepeatedly(Return(false));
1460
1461 EXPECT_CALL(*s_will_remove0, Unload())
1462 .WillOnce(Return(true));
1463 EXPECT_CALL(*s_will_remove1, Unload())
1464 .WillOnce(Return(true));
1465 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001466 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001467 EXPECT_CALL(*s_will_not_remove1, Unload())
1468 .WillOnce(Return(false));
1469
Philipp Neubeck79173602012-11-13 21:10:09 +01001470 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1471 // profile list.
1472 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1473 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1474
Paul Stewart65512e12012-03-26 18:01:08 -07001475 // This will pop profile1, which should cause all our profiles to unload.
1476 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001477 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001478
1479 // 2 of the 4 services added above should have been unregistered and
1480 // removed, leaving 2.
1481 EXPECT_EQ(2, manager()->services_.size());
1482 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1483 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001484
1485 // Expect the unloaded services to lose their profile reference.
1486 EXPECT_FALSE(s_will_remove0->profile());
1487 EXPECT_FALSE(s_will_remove1->profile());
1488
1489 // If we explicitly deregister a service, the effect should be the same
1490 // with respect to the profile reference.
1491 ASSERT_TRUE(s_will_not_remove0->profile());
1492 manager()->DeregisterService(s_will_not_remove0);
1493 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001494}
1495
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001496TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001497 {
1498 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001499 ::DBus::Variant offline_mode;
1500 offline_mode.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001501 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1502 flimflam::kOfflineModeProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001503 offline_mode,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001504 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001505 }
1506 {
1507 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001508 ::DBus::Variant country;
1509 country.writer().append_string("a_country");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001510 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1511 flimflam::kCountryProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001512 country,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001513 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001514 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001515 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001516 {
1517 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001518 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1519 flimflam::kCountryProperty,
1520 PropertyStoreTest::kBoolV,
1521 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001522 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001523 }
1524 {
1525 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001526 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1527 flimflam::kOfflineModeProperty,
1528 PropertyStoreTest::kStringV,
1529 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001530 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001531 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001532 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001533 {
1534 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001535 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001536 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001537 flimflam::kEnabledTechnologiesProperty,
1538 PropertyStoreTest::kStringsV,
1539 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001540 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001541 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001542}
1543
mukesh agrawal32399322011-09-01 10:53:43 -07001544TEST_F(ManagerTest, RequestScan) {
1545 {
1546 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001547 manager()->RegisterDevice(mock_devices_[0].get());
1548 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001549 EXPECT_CALL(*mock_devices_[0], technology())
1550 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001551 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _, _));
Joshua Krollda798622012-06-05 12:30:48 -07001552 EXPECT_CALL(*mock_devices_[1], technology())
1553 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001554 EXPECT_CALL(*mock_devices_[1], Scan(_, _, _)).Times(0);
Wade Guthrie68d41092013-04-02 12:56:02 -07001555 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001556 }
1557
1558 {
1559 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001560 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001561 EXPECT_EQ(Error::kInvalidArguments, error.type());
1562 }
1563}
1564
Darin Petkovb65c2452012-02-23 15:17:06 +01001565TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001566 KeyValueStore args;
1567 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001568 manager()->GetService(args, &e);
1569 EXPECT_EQ(Error::kInvalidArguments, e.type());
1570 EXPECT_EQ("must specify service type", e.message());
1571}
1572
1573TEST_F(ManagerTest, GetServiceUnknownType) {
1574 KeyValueStore args;
1575 Error e;
1576 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1577 manager()->GetService(args, &e);
1578 EXPECT_EQ(Error::kNotSupported, e.type());
1579 EXPECT_EQ("service type is unsupported", e.message());
1580}
1581
Paul Stewart35eff132013-04-12 12:08:40 -07001582TEST_F(ManagerTest, GetServiceEthernetEap) {
1583 KeyValueStore args;
1584 Error e;
Paul Stewart55fc64c2013-07-18 09:51:35 -07001585 ServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1586 dispatcher(),
1587 metrics(),
1588 manager());
Paul Stewart35eff132013-04-12 12:08:40 -07001589 args.SetString(flimflam::kTypeProperty, kTypeEthernetEap);
1590 SetEapProviderService(service);
1591 EXPECT_EQ(service, manager()->GetService(args, &e));
1592 EXPECT_TRUE(e.IsSuccess());
1593}
1594
Darin Petkovb65c2452012-02-23 15:17:06 +01001595TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001596 KeyValueStore args;
1597 Error e;
1598 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001599 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001600 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001601 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001602 manager()->GetService(args, &e);
1603 EXPECT_TRUE(e.IsSuccess());
1604}
1605
Darin Petkov33af05c2012-02-28 10:10:30 +01001606TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1607 KeyValueStore args;
1608 Error e;
1609 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001610 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001611 new StrictMock<MockProfile>(
1612 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001613 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001614 ServiceRefPtr service = manager()->GetService(args, &e);
1615 EXPECT_EQ(Error::kNotSupported, e.type());
1616 EXPECT_FALSE(service);
1617}
1618
Darin Petkovb65c2452012-02-23 15:17:06 +01001619TEST_F(ManagerTest, GetServiceVPN) {
1620 KeyValueStore args;
1621 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001622 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001623 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001624 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001625 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001626 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001627 new StrictMock<MockProfile>(
1628 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001629 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001630
1631#if defined(DISABLE_VPN)
1632
1633 ServiceRefPtr service = manager()->GetService(args, &e);
1634 EXPECT_EQ(Error::kNotSupported, e.type());
1635 EXPECT_FALSE(service);
1636
1637#else
1638
Paul Stewart7f5ad572012-06-04 15:18:54 -07001639 ServiceRefPtr updated_service;
1640 EXPECT_CALL(*profile, UpdateService(_))
1641 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1642 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001643 EXPECT_CALL(*profile, LoadService(_))
1644 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001645 EXPECT_CALL(*profile, ConfigureService(_))
1646 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001647 ServiceRefPtr service = manager()->GetService(args, &e);
1648 EXPECT_TRUE(e.IsSuccess());
1649 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001650 EXPECT_EQ(service, updated_service);
1651 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001652
1653#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001654}
1655
Darin Petkovc63dcf02012-05-24 11:51:43 +02001656TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1657 KeyValueStore args;
1658 Error e;
1659 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1660 ServiceRefPtr service = manager()->GetService(args, &e);
1661 EXPECT_EQ(Error::kInvalidArguments, e.type());
1662 EXPECT_EQ("Missing WiMAX network id.", e.message());
1663 EXPECT_FALSE(service);
1664}
1665
Darin Petkovd1cd7972012-05-22 15:26:15 +02001666TEST_F(ManagerTest, GetServiceWiMax) {
1667 KeyValueStore args;
1668 Error e;
1669 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001670 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1671 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1672 ServiceRefPtr service = manager()->GetService(args, &e);
1673 EXPECT_TRUE(e.IsSuccess());
1674 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001675}
1676
Paul Stewart7f61e522012-03-22 11:13:45 -07001677TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1678 // Manager calls ActiveProfile() so we need at least one profile installed.
1679 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001680 new NiceMock<MockProfile>(
1681 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001682 AdoptProfile(manager(), profile);
1683
1684 KeyValueStore args;
1685 args.SetString(flimflam::kProfileProperty, "xxx");
1686 Error error;
1687 manager()->ConfigureService(args, &error);
1688 EXPECT_EQ(Error::kInvalidArguments, error.type());
1689 EXPECT_EQ("Invalid profile name xxx", error.message());
1690}
1691
1692TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1693 // Manager calls ActiveProfile() so we need at least one profile installed.
1694 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001695 new NiceMock<MockProfile>(
1696 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001697 AdoptProfile(manager(), profile);
1698
1699 KeyValueStore args;
1700 Error error;
1701 manager()->ConfigureService(args, &error);
1702 EXPECT_EQ(Error::kInvalidArguments, error.type());
1703 EXPECT_EQ("must specify service type", error.message());
1704}
1705
1706// A registered service in the ephemeral profile should be moved to the
1707// active profile as a part of configuration if no profile was explicitly
1708// specified.
1709TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1710 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001711 new NiceMock<MockProfile>(
1712 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001713
1714 AdoptProfile(manager(), profile); // This is now the active profile.
1715
Paul Stewartd2e1c362013-03-03 19:06:07 -08001716 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001717 scoped_refptr<MockWiFiService> service(
1718 new NiceMock<MockWiFiService>(control_interface(),
1719 dispatcher(),
1720 metrics(),
1721 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001722 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001723 ssid,
1724 "",
1725 "",
1726 false));
1727
1728 manager()->RegisterService(service);
1729 service->set_profile(GetEphemeralProfile(manager()));
1730
Paul Stewart3c504012013-01-17 17:49:58 -08001731 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001732 .WillOnce(Return(service));
1733 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1734 .WillOnce(Return(true));
1735 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1736 .WillOnce(Return(true));
1737
1738 KeyValueStore args;
1739 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1740 Error error;
1741 manager()->ConfigureService(args, &error);
1742 EXPECT_TRUE(error.IsSuccess());
1743}
1744
Paul Stewart2c575d22012-12-07 12:28:57 -08001745// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001746// specify a profile, it should be moved from the profile it was previously
1747// in to the specified profile if one was requested.
1748TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1749 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001750 new NiceMock<MockProfile>(
1751 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001752 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001753 new NiceMock<MockProfile>(
1754 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001755
1756 const string kProfileName0 = "profile0";
1757 const string kProfileName1 = "profile1";
1758
1759 EXPECT_CALL(*profile0, GetRpcIdentifier())
1760 .WillRepeatedly(Return(kProfileName0));
1761 EXPECT_CALL(*profile1, GetRpcIdentifier())
1762 .WillRepeatedly(Return(kProfileName1));
1763
1764 AdoptProfile(manager(), profile0);
1765 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1766
Paul Stewartd2e1c362013-03-03 19:06:07 -08001767 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001768 scoped_refptr<MockWiFiService> service(
1769 new NiceMock<MockWiFiService>(control_interface(),
1770 dispatcher(),
1771 metrics(),
1772 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001773 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001774 ssid,
1775 "",
1776 "",
1777 false));
1778
1779 manager()->RegisterService(service);
1780 service->set_profile(profile1);
1781
Paul Stewart3c504012013-01-17 17:49:58 -08001782 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001783 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001784 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1785 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001786 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1787 .WillOnce(Return(true));
1788 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1789 .WillOnce(Return(true));
1790 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1791 .WillOnce(Return(true));
1792
1793 KeyValueStore args;
1794 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1795 args.SetString(flimflam::kProfileProperty, kProfileName0);
1796 Error error;
1797 manager()->ConfigureService(args, &error);
1798 EXPECT_TRUE(error.IsSuccess());
1799 service->set_profile(NULL); // Breaks refcounting loop.
1800}
1801
Paul Stewart2c575d22012-12-07 12:28:57 -08001802// If we configure a service that is already a member of the specified
1803// profile, the Manager should not call LoadService or AdoptService again
1804// on this service.
1805TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1806 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001807 new NiceMock<MockProfile>(
1808 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001809
1810 const string kProfileName0 = "profile0";
1811
1812 EXPECT_CALL(*profile0, GetRpcIdentifier())
1813 .WillRepeatedly(Return(kProfileName0));
1814
1815 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1816
Paul Stewartd2e1c362013-03-03 19:06:07 -08001817 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001818 scoped_refptr<MockWiFiService> service(
1819 new NiceMock<MockWiFiService>(control_interface(),
1820 dispatcher(),
1821 metrics(),
1822 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001823 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001824 ssid,
1825 "",
1826 "",
1827 false));
1828
1829 manager()->RegisterService(service);
1830 service->set_profile(profile0);
1831
Paul Stewart3c504012013-01-17 17:49:58 -08001832 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001833 .WillOnce(Return(service));
1834 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1835 .Times(0);
1836 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1837 .WillOnce(Return(true));
1838 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1839 .Times(0);
1840
1841 KeyValueStore args;
1842 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1843 args.SetString(flimflam::kProfileProperty, kProfileName0);
1844 Error error;
1845 manager()->ConfigureService(args, &error);
1846 EXPECT_TRUE(error.IsSuccess());
1847 service->set_profile(NULL); // Breaks refcounting loop.
1848}
1849
Paul Stewart7f61e522012-03-22 11:13:45 -07001850// An unregistered service should remain unregistered, but its contents should
1851// be saved to the specified profile nonetheless.
1852TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1853 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001854 new NiceMock<MockProfile>(
1855 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001856 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001857 new NiceMock<MockProfile>(
1858 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001859
1860 const string kProfileName0 = "profile0";
1861 const string kProfileName1 = "profile1";
1862
1863 EXPECT_CALL(*profile0, GetRpcIdentifier())
1864 .WillRepeatedly(Return(kProfileName0));
1865 EXPECT_CALL(*profile1, GetRpcIdentifier())
1866 .WillRepeatedly(Return(kProfileName1));
1867
1868 AdoptProfile(manager(), profile0);
1869 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1870
Paul Stewartd2e1c362013-03-03 19:06:07 -08001871 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001872 scoped_refptr<MockWiFiService> service(
1873 new NiceMock<MockWiFiService>(control_interface(),
1874 dispatcher(),
1875 metrics(),
1876 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001877 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001878 ssid,
1879 "",
1880 "",
1881 false));
1882
1883 service->set_profile(profile1);
1884
Paul Stewart3c504012013-01-17 17:49:58 -08001885 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001886 .WillOnce(Return(service));
1887 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1888 .WillOnce(Return(true));
1889 EXPECT_CALL(*profile0, AdoptService(_))
1890 .Times(0);
1891 EXPECT_CALL(*profile1, AdoptService(_))
1892 .Times(0);
1893
1894 KeyValueStore args;
1895 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1896 args.SetString(flimflam::kProfileProperty, kProfileName0);
1897 Error error;
1898 manager()->ConfigureService(args, &error);
1899 EXPECT_TRUE(error.IsSuccess());
1900}
1901
Paul Stewartd2e1c362013-03-03 19:06:07 -08001902TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1903 KeyValueStore args;
1904 Error error;
1905 ServiceRefPtr service =
1906 manager()->ConfigureServiceForProfile("", args, &error);
Paul Stewart6ae05892013-07-29 12:21:12 -07001907 EXPECT_EQ(Error::kInvalidArguments, error.type());
1908 EXPECT_EQ("must specify service type", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001909 EXPECT_EQ(NULL, service.get());
1910}
1911
1912TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1913 KeyValueStore args;
1914 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1915 Error error;
1916 ServiceRefPtr service =
1917 manager()->ConfigureServiceForProfile("", args, &error);
1918 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07001919 EXPECT_EQ("service type is unsupported", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001920 EXPECT_EQ(NULL, service.get());
1921}
1922
1923TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1924 KeyValueStore args;
1925 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1926 Error error;
1927 ServiceRefPtr service =
1928 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1929 EXPECT_EQ(Error::kNotFound, error.type());
1930 EXPECT_EQ("Profile specified was not found", error.message());
1931 EXPECT_EQ(NULL, service.get());
1932}
1933
1934TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1935 const string kProfileName0 = "profile0";
1936 const string kProfileName1 = "profile1";
1937 scoped_refptr<MockProfile> profile0(
1938 AddNamedMockProfileToManager(manager(), kProfileName0));
1939
1940 KeyValueStore args;
1941 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1942 args.SetString(flimflam::kProfileProperty, kProfileName1);
1943 Error error;
1944 ServiceRefPtr service =
1945 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1946 EXPECT_EQ(Error::kInvalidArguments, error.type());
1947 EXPECT_EQ("Profile argument does not match that in "
1948 "the configuration arguments", error.message());
1949 EXPECT_EQ(NULL, service.get());
1950}
1951
1952TEST_F(ManagerTest,
1953 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1954 const string kProfileName0 = "profile0";
1955 scoped_refptr<MockProfile> profile0(
1956 AddNamedMockProfileToManager(manager(), kProfileName0));
1957 KeyValueStore args;
1958 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1959 args.SetString(flimflam::kProfileProperty, kProfileName0);
1960
1961 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1962 .WillOnce(Return(WiFiServiceRefPtr()));
1963 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1964 .WillOnce(Return(WiFiServiceRefPtr()));
1965 Error error;
1966 ServiceRefPtr service =
1967 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1968 // Since we didn't set the error in the GetService expectation above...
1969 EXPECT_TRUE(error.IsSuccess());
1970 EXPECT_EQ(NULL, service.get());
1971}
1972
1973TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1974 const string kProfileName0 = "profile0";
1975 scoped_refptr<MockProfile> profile0(
1976 AddNamedMockProfileToManager(manager(), kProfileName0));
1977
1978 KeyValueStore args;
1979 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1980
1981 scoped_refptr<MockWiFiService> mock_service(
1982 new NiceMock<MockWiFiService>(control_interface(),
1983 dispatcher(),
1984 metrics(),
1985 manager(),
1986 wifi_provider_,
1987 vector<uint8_t>(),
1988 flimflam::kModeManaged,
1989 flimflam::kSecurityNone,
1990 false));
1991 ServiceRefPtr mock_service_generic(mock_service.get());
1992 mock_service->set_profile(profile0);
1993 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1994 .WillOnce(Return(WiFiServiceRefPtr()));
1995 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1996 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1997 .WillOnce(Return(true));
1998 Error error;
1999 ServiceRefPtr service =
2000 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2001 EXPECT_TRUE(error.IsSuccess());
2002 EXPECT_EQ(mock_service.get(), service.get());
2003 mock_service->set_profile(NULL); // Breaks reference cycle.
2004}
2005
2006TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
2007 scoped_refptr<MockService> mock_service(
2008 new NiceMock<MockService>(control_interface(),
2009 dispatcher(),
2010 metrics(),
2011 manager()));
2012 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002013 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002014 manager()->RegisterService(mock_service);
2015 ServiceRefPtr mock_service_generic(mock_service.get());
2016
2017 const string kProfileName = "profile";
2018 scoped_refptr<MockProfile> profile(
2019 AddNamedMockProfileToManager(manager(), kProfileName));
2020 mock_service->set_profile(profile);
2021
2022 EXPECT_CALL(*mock_service, technology())
2023 .WillOnce(Return(Technology::kCellular))
2024 .WillOnce(Return(Technology::kWifi));
2025
2026 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
2027 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2028 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2029
2030 KeyValueStore args;
2031 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2032 args.SetString(flimflam::kGuidProperty, kGUID);
2033
2034 // The first attempt should fail because the service reports a technology
2035 // other than "WiFi".
2036 {
2037 Error error;
2038 ServiceRefPtr service =
2039 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2040 EXPECT_EQ(NULL, service.get());
2041 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07002042 EXPECT_EQ("This GUID matches a non-wifi service", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08002043 }
2044
2045 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2046 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2047
2048 {
2049 Error error;
2050 ServiceRefPtr service =
2051 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2052 EXPECT_TRUE(error.IsSuccess());
2053 EXPECT_EQ(mock_service.get(), service.get());
2054 EXPECT_EQ(profile.get(), service->profile().get());
2055 }
2056 mock_service->set_profile(NULL); // Breaks reference cycle.
2057}
2058
2059TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
2060 const string kProfileName = "profile";
2061 scoped_refptr<MockProfile> profile(
2062 AddNamedMockProfileToManager(manager(), kProfileName));
2063
2064 scoped_refptr<MockWiFiService> mock_service(
2065 new NiceMock<MockWiFiService>(control_interface(),
2066 dispatcher(),
2067 metrics(),
2068 manager(),
2069 wifi_provider_,
2070 vector<uint8_t>(),
2071 flimflam::kModeManaged,
2072 flimflam::kSecurityNone,
2073 false));
2074 mock_service->set_profile(profile);
2075 ServiceRefPtr mock_service_generic(mock_service.get());
2076
2077 KeyValueStore args;
2078 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2079 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2080 .WillOnce(Return(mock_service));
2081 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2082 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2083 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2084 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2085
2086 Error error;
2087 ServiceRefPtr service =
2088 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2089 EXPECT_TRUE(error.IsSuccess());
2090 EXPECT_EQ(mock_service.get(), service.get());
2091 EXPECT_EQ(profile.get(), service->profile().get());
2092 mock_service->set_profile(NULL); // Breaks reference cycle.
2093}
2094
2095TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2096 const string kProfileName = "profile";
2097 scoped_refptr<MockProfile> profile(
2098 AddNamedMockProfileToManager(manager(), kProfileName));
2099
2100 scoped_refptr<MockWiFiService> mock_service(
2101 new NiceMock<MockWiFiService>(control_interface(),
2102 dispatcher(),
2103 metrics(),
2104 manager(),
2105 wifi_provider_,
2106 vector<uint8_t>(),
2107 flimflam::kModeManaged,
2108 flimflam::kSecurityNone,
2109 false));
2110 mock_service->set_profile(GetEphemeralProfile(manager()));
2111 ServiceRefPtr mock_service_generic(mock_service.get());
2112
2113 KeyValueStore args;
2114 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2115 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2116 .WillOnce(Return(mock_service));
2117 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2118 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2119 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2120
2121 Error error;
2122 ServiceRefPtr service =
2123 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2124 EXPECT_TRUE(error.IsSuccess());
2125 EXPECT_EQ(mock_service.get(), service.get());
2126 EXPECT_EQ(profile.get(), service->profile().get());
2127 mock_service->set_profile(NULL); // Breaks reference cycle.
2128}
2129
2130TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2131 const string kProfileName0 = "profile0";
2132 scoped_refptr<MockProfile> profile0(
2133 AddNamedMockProfileToManager(manager(), kProfileName0));
2134 const string kProfileName1 = "profile1";
2135 scoped_refptr<MockProfile> profile1(
2136 AddNamedMockProfileToManager(manager(), kProfileName1));
2137
2138 scoped_refptr<MockWiFiService> mock_service(
2139 new NiceMock<MockWiFiService>(control_interface(),
2140 dispatcher(),
2141 metrics(),
2142 manager(),
2143 wifi_provider_,
2144 vector<uint8_t>(),
2145 flimflam::kModeManaged,
2146 flimflam::kSecurityNone,
2147 false));
2148 manager()->RegisterService(mock_service);
2149 mock_service->set_profile(profile0);
2150 ServiceRefPtr mock_service_generic(mock_service.get());
2151
2152 KeyValueStore args;
2153 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2154 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2155 .WillOnce(Return(mock_service));
2156 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2157 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2158 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2159 // This happens once to make the service loadable for the ConfigureService
2160 // below, and a second time after the service is modified.
2161 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2162 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2163 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2164 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2165
2166 Error error;
2167 ServiceRefPtr service =
2168 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2169 EXPECT_TRUE(error.IsSuccess());
2170 EXPECT_EQ(mock_service.get(), service.get());
2171 mock_service->set_profile(NULL); // Breaks reference cycle.
2172}
2173
2174TEST_F(ManagerTest,
2175 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2176 const string kProfileName0 = "profile0";
2177 scoped_refptr<MockProfile> profile0(
2178 AddNamedMockProfileToManager(manager(), kProfileName0));
2179 const string kProfileName1 = "profile1";
2180 scoped_refptr<MockProfile> profile1(
2181 AddNamedMockProfileToManager(manager(), kProfileName1));
2182
2183 scoped_refptr<MockWiFiService> matching_service(
2184 new StrictMock<MockWiFiService>(control_interface(),
2185 dispatcher(),
2186 metrics(),
2187 manager(),
2188 wifi_provider_,
2189 vector<uint8_t>(),
2190 flimflam::kModeManaged,
2191 flimflam::kSecurityNone,
2192 false));
2193 matching_service->set_profile(profile1);
2194
2195 // We need to get rid of our reference to this mock service as soon
2196 // as Manager::ConfigureServiceForProfile() takes a reference in its
2197 // call to WiFiProvider::CreateTemporaryService(). This way the
2198 // latter function can keep a DCHECK(service->HasOneRef() even in
2199 // unit tests.
2200 temp_mock_service_ =
2201 new NiceMock<MockWiFiService>(control_interface(),
2202 dispatcher(),
2203 metrics(),
2204 manager(),
2205 wifi_provider_,
2206 vector<uint8_t>(),
2207 flimflam::kModeManaged,
2208 flimflam::kSecurityNone,
2209 false);
2210
2211 // Only hold a pointer here so we don't affect the refcount.
2212 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2213
2214 KeyValueStore args;
2215 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2216 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2217 .WillOnce(Return(matching_service));
2218 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2219 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2220 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2221 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2222 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2223 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2224 .Times(1);
2225 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2226 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2227
2228 Error error;
2229 ServiceRefPtr service =
2230 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2231 EXPECT_TRUE(error.IsSuccess());
2232 EXPECT_EQ(NULL, service.get());
2233 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2234}
2235
Paul Stewart7a20aa42013-01-17 12:21:41 -08002236TEST_F(ManagerTest, FindMatchingService) {
2237 KeyValueStore args;
2238 {
2239 Error error;
2240 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2241 EXPECT_EQ(Error::kNotFound, error.type());
2242 }
2243
2244 scoped_refptr<MockService> mock_service0(
2245 new NiceMock<MockService>(control_interface(),
2246 dispatcher(),
2247 metrics(),
2248 manager()));
2249 scoped_refptr<MockService> mock_service1(
2250 new NiceMock<MockService>(control_interface(),
2251 dispatcher(),
2252 metrics(),
2253 manager()));
2254 manager()->RegisterService(mock_service0);
2255 manager()->RegisterService(mock_service1);
2256 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2257 .WillOnce(Return(true))
2258 .WillRepeatedly(Return(false));
2259 {
2260 Error error;
2261 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2262 EXPECT_TRUE(error.IsSuccess());
2263 }
2264 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2265 .WillOnce(Return(true))
2266 .WillRepeatedly(Return(false));
2267 {
2268 Error error;
2269 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2270 EXPECT_TRUE(error.IsSuccess());
2271 }
2272 {
2273 Error error;
2274 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2275 EXPECT_EQ(Error::kNotFound, error.type());
2276 }
2277}
2278
Paul Stewart22aa71b2011-09-16 12:15:11 -07002279TEST_F(ManagerTest, TechnologyOrder) {
2280 Error error;
2281 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2282 string(flimflam::kTypeWifi), &error);
2283 ASSERT_TRUE(error.IsSuccess());
2284 EXPECT_EQ(manager()->GetTechnologyOrder(),
2285 string(flimflam::kTypeEthernet) + "," +
2286 string(flimflam::kTypeWifi));
2287
2288 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2289 string(flimflam::kTypeWifi), &error);
2290 ASSERT_FALSE(error.IsSuccess());
2291 EXPECT_EQ(Error::kInvalidArguments, error.type());
2292 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2293 string(flimflam::kTypeWifi),
2294 manager()->GetTechnologyOrder());
2295}
2296
2297TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002298 // TODO(quiche): Some of these tests would probably fit better in
2299 // service_unittest, since the actual comparison of Services is
Paul Stewartee6b3d72013-07-12 16:07:51 -07002300 // implemented in Service. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002301
Paul Stewart22aa71b2011-09-16 12:15:11 -07002302 scoped_refptr<MockService> mock_service0(
2303 new NiceMock<MockService>(control_interface(),
2304 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002305 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002306 manager()));
2307 scoped_refptr<MockService> mock_service1(
2308 new NiceMock<MockService>(control_interface(),
2309 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002310 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002311 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002312
2313 manager()->RegisterService(mock_service0);
2314 manager()->RegisterService(mock_service1);
2315
Darin Petkov457728b2013-01-09 09:49:08 +01002316 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002317 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2318
2319 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002320 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002321 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2322
2323 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002324 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002325 manager()->UpdateService(mock_service1);
2326 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2327
2328 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002329 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002330 manager()->UpdateService(mock_service0);
2331 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2332
2333 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002334 EXPECT_CALL(*mock_service0.get(), technology())
2335 .WillRepeatedly(Return((Technology::kWifi)));
2336 EXPECT_CALL(*mock_service1.get(), technology())
2337 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002338
2339 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002340 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002341 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002342 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2343
2344 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2345 string(flimflam::kTypeEthernet), &error);
2346 EXPECT_TRUE(error.IsSuccess());
2347 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2348
Gaurav Shah435de2c2011-11-17 19:01:07 -08002349 // Priority.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002350 mock_service0->SetPriority(1, NULL);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002351 manager()->UpdateService(mock_service0);
2352 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2353
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002354 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002355 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002356 manager()->UpdateService(mock_service1);
2357 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2358
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002359 // Auto-connect.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002360 mock_service0->SetAutoConnect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002361 manager()->UpdateService(mock_service0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002362 mock_service1->SetAutoConnect(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002363 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002364 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2365
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002366 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2367 // to any of the others below, so we reset to the default state after
2368 // testing.
2369 EXPECT_CALL(*mock_service1.get(),
2370 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2371 .WillOnce(Return(true))
2372 .WillRepeatedly(Return(false));
2373 manager()->UpdateService(mock_service1);
2374 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2375 manager()->UpdateService(mock_service0);
2376 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2377
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002378 // Connectable.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002379 mock_service1->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002380 manager()->UpdateService(mock_service1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002381 mock_service0->SetConnectable(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002382 manager()->UpdateService(mock_service0);
2383 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2384
2385 // IsFailed.
2386 EXPECT_CALL(*mock_service0.get(), state())
2387 .WillRepeatedly(Return(Service::kStateIdle));
2388 EXPECT_CALL(*mock_service0.get(), IsFailed())
2389 .WillRepeatedly(Return(false));
2390 manager()->UpdateService(mock_service0);
2391 EXPECT_CALL(*mock_service0.get(), state())
2392 .WillRepeatedly(Return(Service::kStateFailure));
2393 EXPECT_CALL(*mock_service1.get(), IsFailed())
2394 .WillRepeatedly(Return(true));
2395 manager()->UpdateService(mock_service1);
2396 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2397
2398 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002399 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002400 .WillRepeatedly(Return(Service::kStateAssociating));
2401 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002402 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002403 manager()->UpdateService(mock_service1);
2404 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2405
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002406 // Connected.
2407 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002408 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002409 EXPECT_CALL(*mock_service0.get(), IsConnected())
2410 .WillRepeatedly(Return(true));
2411 manager()->UpdateService(mock_service0);
2412 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2413
Paul Stewarta121c442012-06-09 14:12:58 -07002414 // Portal.
2415 EXPECT_CALL(*mock_service1.get(), state())
2416 .WillRepeatedly(Return(Service::kStateConnected));
2417 EXPECT_CALL(*mock_service1.get(), IsConnected())
2418 .WillRepeatedly(Return(true));
2419 manager()->UpdateService(mock_service1);
2420 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2421
Paul Stewart22aa71b2011-09-16 12:15:11 -07002422 manager()->DeregisterService(mock_service0);
2423 manager()->DeregisterService(mock_service1);
2424}
2425
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002426TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002427 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002428 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002429
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002430 scoped_refptr<MockService> mock_service0(
2431 new NiceMock<MockService>(control_interface(),
2432 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002433 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002434 manager()));
2435 scoped_refptr<MockService> mock_service1(
2436 new NiceMock<MockService>(control_interface(),
2437 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002438 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002439 manager()));
2440
2441 scoped_refptr<MockConnection> mock_connection0(
2442 new NiceMock<MockConnection>(device_info_.get()));
2443 scoped_refptr<MockConnection> mock_connection1(
2444 new NiceMock<MockConnection>(device_info_.get()));
2445
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002446 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002447 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002448 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002449 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002450 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002451 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002452
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002453 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002454 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002455
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002456 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002457 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002458 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002459
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002460 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002461 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002462 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002463
Paul Stewartce4ec192012-03-14 12:53:46 -07002464 mock_service0->set_mock_connection(mock_connection0);
2465 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002466
2467 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002468 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002469 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002470
Darin Petkova5e07ef2012-07-09 14:27:57 +02002471 ServiceWatcher service_watcher;
2472 int tag =
2473 manager()->RegisterDefaultServiceCallback(
2474 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2475 service_watcher.AsWeakPtr()));
2476 EXPECT_EQ(1, tag);
2477
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002478 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002479 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2480 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002481 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002482 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002483 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002484
Darin Petkova5e07ef2012-07-09 14:27:57 +02002485 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002486 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002487 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002488 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002489 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002490 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002491 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002492
Paul Stewartce4ec192012-03-14 12:53:46 -07002493 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002494 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002495 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002496 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002497
2498 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002499 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002500}
2501
Darin Petkova5e07ef2012-07-09 14:27:57 +02002502TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2503 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2504 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2505
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002506 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002507 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002508
2509 scoped_refptr<MockService> mock_service(
2510 new NiceMock<MockService>(
2511 control_interface(), dispatcher(), metrics(), manager()));
2512 ServiceRefPtr service = mock_service;
2513 ServiceRefPtr null_service;
2514
2515 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2516 manager()->NotifyDefaultServiceChanged(null_service);
2517
2518 ServiceWatcher service_watcher1;
2519 ServiceWatcher service_watcher2;
2520 int tag1 =
2521 manager()->RegisterDefaultServiceCallback(
2522 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2523 service_watcher1.AsWeakPtr()));
2524 EXPECT_EQ(1, tag1);
2525 int tag2 =
2526 manager()->RegisterDefaultServiceCallback(
2527 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2528 service_watcher2.AsWeakPtr()));
2529 EXPECT_EQ(2, tag2);
2530
2531 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2532 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2533 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2534 manager()->NotifyDefaultServiceChanged(null_service);
2535
2536 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2537 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2538 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2539 manager()->NotifyDefaultServiceChanged(mock_service);
2540
2541 manager()->DeregisterDefaultServiceCallback(tag1);
2542 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2543 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2544 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2545 manager()->NotifyDefaultServiceChanged(mock_service);
2546 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2547
2548 manager()->DeregisterDefaultServiceCallback(tag2);
2549 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2550 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2551 manager()->NotifyDefaultServiceChanged(mock_service);
2552
2553 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2554 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2555}
2556
Gaurav Shah435de2c2011-11-17 19:01:07 -08002557TEST_F(ManagerTest, AvailableTechnologies) {
2558 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2559 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002560 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002561 manager(),
2562 "null4",
2563 "addr4",
2564 0));
2565 manager()->RegisterDevice(mock_devices_[0]);
2566 manager()->RegisterDevice(mock_devices_[1]);
2567 manager()->RegisterDevice(mock_devices_[2]);
2568 manager()->RegisterDevice(mock_devices_[3]);
2569
2570 ON_CALL(*mock_devices_[0].get(), technology())
2571 .WillByDefault(Return(Technology::kEthernet));
2572 ON_CALL(*mock_devices_[1].get(), technology())
2573 .WillByDefault(Return(Technology::kWifi));
2574 ON_CALL(*mock_devices_[2].get(), technology())
2575 .WillByDefault(Return(Technology::kCellular));
2576 ON_CALL(*mock_devices_[3].get(), technology())
2577 .WillByDefault(Return(Technology::kWifi));
2578
2579 set<string> expected_technologies;
2580 expected_technologies.insert(Technology::NameFromIdentifier(
2581 Technology::kEthernet));
2582 expected_technologies.insert(Technology::NameFromIdentifier(
2583 Technology::kWifi));
2584 expected_technologies.insert(Technology::NameFromIdentifier(
2585 Technology::kCellular));
2586 Error error;
2587 vector<string> technologies = manager()->AvailableTechnologies(&error);
2588
2589 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2590 ContainerEq(expected_technologies));
2591}
2592
2593TEST_F(ManagerTest, ConnectedTechnologies) {
2594 scoped_refptr<MockService> connected_service1(
2595 new NiceMock<MockService>(control_interface(),
2596 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002597 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002598 manager()));
2599 scoped_refptr<MockService> connected_service2(
2600 new NiceMock<MockService>(control_interface(),
2601 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002602 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002603 manager()));
2604 scoped_refptr<MockService> disconnected_service1(
2605 new NiceMock<MockService>(control_interface(),
2606 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002607 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002608 manager()));
2609 scoped_refptr<MockService> disconnected_service2(
2610 new NiceMock<MockService>(control_interface(),
2611 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002612 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002613 manager()));
2614
2615 ON_CALL(*connected_service1.get(), IsConnected())
2616 .WillByDefault(Return(true));
2617 ON_CALL(*connected_service2.get(), IsConnected())
2618 .WillByDefault(Return(true));
2619
2620 manager()->RegisterService(connected_service1);
2621 manager()->RegisterService(connected_service2);
2622 manager()->RegisterService(disconnected_service1);
2623 manager()->RegisterService(disconnected_service2);
2624
2625 manager()->RegisterDevice(mock_devices_[0]);
2626 manager()->RegisterDevice(mock_devices_[1]);
2627 manager()->RegisterDevice(mock_devices_[2]);
2628 manager()->RegisterDevice(mock_devices_[3]);
2629
2630 ON_CALL(*mock_devices_[0].get(), technology())
2631 .WillByDefault(Return(Technology::kEthernet));
2632 ON_CALL(*mock_devices_[1].get(), technology())
2633 .WillByDefault(Return(Technology::kWifi));
2634 ON_CALL(*mock_devices_[2].get(), technology())
2635 .WillByDefault(Return(Technology::kCellular));
2636 ON_CALL(*mock_devices_[3].get(), technology())
2637 .WillByDefault(Return(Technology::kWifi));
2638
2639 mock_devices_[0]->SelectService(connected_service1);
2640 mock_devices_[1]->SelectService(disconnected_service1);
2641 mock_devices_[2]->SelectService(disconnected_service2);
2642 mock_devices_[3]->SelectService(connected_service2);
2643
2644 set<string> expected_technologies;
2645 expected_technologies.insert(Technology::NameFromIdentifier(
2646 Technology::kEthernet));
2647 expected_technologies.insert(Technology::NameFromIdentifier(
2648 Technology::kWifi));
2649 Error error;
2650
2651 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2652 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2653 ContainerEq(expected_technologies));
2654}
2655
2656TEST_F(ManagerTest, DefaultTechnology) {
2657 scoped_refptr<MockService> connected_service(
2658 new NiceMock<MockService>(control_interface(),
2659 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002660 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002661 manager()));
2662 scoped_refptr<MockService> disconnected_service(
2663 new NiceMock<MockService>(control_interface(),
2664 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002665 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002666 manager()));
2667
2668 // Connected. WiFi.
2669 ON_CALL(*connected_service.get(), IsConnected())
2670 .WillByDefault(Return(true));
2671 ON_CALL(*connected_service.get(), state())
2672 .WillByDefault(Return(Service::kStateConnected));
2673 ON_CALL(*connected_service.get(), technology())
2674 .WillByDefault(Return(Technology::kWifi));
2675
2676 // Disconnected. Ethernet.
2677 ON_CALL(*disconnected_service.get(), technology())
2678 .WillByDefault(Return(Technology::kEthernet));
2679
2680 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002681 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002682 Error error;
2683 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2684
2685
2686 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002687 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002688 // Connected service should be brought to the front now.
2689 string expected_technology =
2690 Technology::NameFromIdentifier(Technology::kWifi);
2691 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2692}
2693
Paul Stewart212d60f2012-07-12 10:59:13 -07002694TEST_F(ManagerTest, Stop) {
2695 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002696 new NiceMock<MockProfile>(
2697 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002698 AdoptProfile(manager(), profile);
2699 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002700 new NiceMock<MockService>(control_interface(),
2701 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002702 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002703 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002704 manager()->RegisterService(service);
2705 manager()->RegisterDevice(mock_devices_[0]);
2706 EXPECT_CALL(*profile.get(),
2707 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2708 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002709 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002710 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2711 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002712 manager()->Stop();
2713}
2714
mukesh agrawal00917ce2011-11-22 23:56:55 +00002715TEST_F(ManagerTest, UpdateServiceConnected) {
2716 scoped_refptr<MockService> mock_service(
2717 new NiceMock<MockService>(control_interface(),
2718 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002719 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002720 manager()));
2721 manager()->RegisterService(mock_service);
2722 EXPECT_FALSE(mock_service->favorite());
2723 EXPECT_FALSE(mock_service->auto_connect());
2724
Gaurav Shah435de2c2011-11-17 19:01:07 -08002725 EXPECT_CALL(*mock_service.get(), IsConnected())
2726 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002727 manager()->UpdateService(mock_service);
2728 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2729 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002730 // SortServices test. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002731 EXPECT_TRUE(mock_service->favorite());
2732 EXPECT_TRUE(mock_service->auto_connect());
2733}
2734
Thieu Led4e9e552012-02-16 16:26:07 -08002735TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2736 // This tests the case where the user connects to a service that is
2737 // currently associated with a profile. We want to make sure that the
2738 // favorite flag is set and that the flag is saved to the current
2739 // profile.
2740 scoped_refptr<MockService> mock_service(
2741 new NiceMock<MockService>(control_interface(),
2742 dispatcher(),
2743 metrics(),
2744 manager()));
2745 manager()->RegisterService(mock_service);
2746 EXPECT_FALSE(mock_service->favorite());
2747 EXPECT_FALSE(mock_service->auto_connect());
2748
Gary Moraind93615e2012-04-27 11:50:03 -07002749 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002750 new MockProfile(
2751 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002752
Gary Moraind93615e2012-04-27 11:50:03 -07002753 mock_service->set_profile(profile);
2754 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002755 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002756 EXPECT_CALL(*profile,
2757 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002758 manager()->UpdateService(mock_service);
2759 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2760 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002761 // SortServices test. (crbug.com/206367)
Thieu Led4e9e552012-02-16 16:26:07 -08002762 EXPECT_TRUE(mock_service->favorite());
2763 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002764 // This releases the ref on the mock profile.
2765 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002766}
2767
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002768TEST_F(ManagerTest, SaveSuccessfulService) {
2769 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002770 new StrictMock<MockProfile>(
2771 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002772 AdoptProfile(manager(), profile);
2773 scoped_refptr<MockService> service(
2774 new NiceMock<MockService>(control_interface(),
2775 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002776 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002777 manager()));
2778
2779 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2780 ServiceRefPtr expect_service(service.get());
2781
2782 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2783 .WillOnce(Return(false));
2784 manager()->RegisterService(service);
2785
2786 EXPECT_CALL(*service.get(), state())
2787 .WillRepeatedly(Return(Service::kStateConnected));
2788 EXPECT_CALL(*service.get(), IsConnected())
2789 .WillRepeatedly(Return(true));
2790 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2791 .WillOnce(Return(true));
2792 manager()->UpdateService(service);
2793}
2794
Darin Petkove7c6ad32012-06-29 10:22:09 +02002795TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002796 MockProfile *profile0 =
2797 new MockProfile(control_interface(), metrics(), manager(), "");
2798 MockProfile *profile1 =
2799 new MockProfile(control_interface(), metrics(), manager(), "");
2800 MockProfile *profile2 =
2801 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002802 AdoptProfile(manager(), profile0); // Passes ownership.
2803 AdoptProfile(manager(), profile1); // Passes ownership.
2804 AdoptProfile(manager(), profile2); // Passes ownership.
2805 DeviceRefPtr device_ref(mock_devices_[0].get());
2806 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2807 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2808 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2809 manager()->UpdateDevice(mock_devices_[0]);
2810}
2811
Paul Stewart1b253142012-01-26 14:05:52 -08002812TEST_F(ManagerTest, EnumerateProfiles) {
2813 vector<string> profile_paths;
2814 for (size_t i = 0; i < 10; i++) {
2815 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002816 new StrictMock<MockProfile>(
2817 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002818 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002819 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2820 .WillOnce(Return(profile_paths.back()));
2821 AdoptProfile(manager(), profile);
2822 }
2823
2824 Error error;
2825 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2826 EXPECT_TRUE(error.IsSuccess());
2827 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2828 for (size_t i = 0; i < profile_paths.size(); i++) {
2829 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2830 }
2831}
2832
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002833TEST_F(ManagerTest, AutoConnectOnRegister) {
2834 MockServiceRefPtr service = MakeAutoConnectableService();
2835 EXPECT_CALL(*service.get(), AutoConnect());
2836 manager()->RegisterService(service);
2837 dispatcher()->DispatchPendingEvents();
2838}
2839
2840TEST_F(ManagerTest, AutoConnectOnUpdate) {
2841 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002842 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002843 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002844 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002845 manager()->RegisterService(service1);
2846 manager()->RegisterService(service2);
2847 dispatcher()->DispatchPendingEvents();
2848
2849 EXPECT_CALL(*service1.get(), AutoConnect());
2850 EXPECT_CALL(*service2.get(), state())
2851 .WillRepeatedly(Return(Service::kStateFailure));
2852 EXPECT_CALL(*service2.get(), IsFailed())
2853 .WillRepeatedly(Return(true));
2854 EXPECT_CALL(*service2.get(), IsConnected())
2855 .WillRepeatedly(Return(false));
2856 manager()->UpdateService(service2);
2857 dispatcher()->DispatchPendingEvents();
2858}
2859
2860TEST_F(ManagerTest, AutoConnectOnDeregister) {
2861 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002862 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002863 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002864 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002865 manager()->RegisterService(service1);
2866 manager()->RegisterService(service2);
2867 dispatcher()->DispatchPendingEvents();
2868
2869 EXPECT_CALL(*service1.get(), AutoConnect());
2870 manager()->DeregisterService(service2);
2871 dispatcher()->DispatchPendingEvents();
2872}
2873
Darin Petkov3ec55342012-09-28 14:04:44 +02002874TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2875 MockServiceRefPtr service = MakeAutoConnectableService();
2876 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2877 SetPowerManager();
2878 EXPECT_CALL(*service, AutoConnect()).Times(0);
2879 manager()->RegisterService(service);
2880 dispatcher()->DispatchPendingEvents();
2881}
2882
Darin Petkovca621542012-07-25 14:25:56 +02002883TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2884 MockServiceRefPtr service = MakeAutoConnectableService();
2885 SetPowerState(PowerManagerProxyDelegate::kMem);
2886 SetPowerManager();
2887 EXPECT_CALL(*service, AutoConnect()).Times(0);
2888 manager()->RegisterService(service);
2889 dispatcher()->DispatchPendingEvents();
2890}
2891
2892TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2893 MockServiceRefPtr service = MakeAutoConnectableService();
2894 SetPowerState(PowerManagerProxyDelegate::kOn);
2895 SetPowerManager();
2896 EXPECT_CALL(*service, AutoConnect());
2897 manager()->RegisterService(service);
2898 dispatcher()->DispatchPendingEvents();
2899}
2900
2901TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2902 MockServiceRefPtr service = MakeAutoConnectableService();
2903 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2904 SetPowerManager();
2905 EXPECT_CALL(*service, AutoConnect());
2906 manager()->RegisterService(service);
2907 dispatcher()->DispatchPendingEvents();
2908}
2909
Paul Stewart63864b62012-11-07 15:10:55 -08002910TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2911 SetRunning(false);
2912 MockServiceRefPtr service = MakeAutoConnectableService();
2913 EXPECT_CALL(*service, AutoConnect()).Times(0);
2914 manager()->RegisterService(service);
2915 dispatcher()->DispatchPendingEvents();
2916}
2917
Darin Petkovca621542012-07-25 14:25:56 +02002918TEST_F(ManagerTest, OnPowerStateChanged) {
2919 MockServiceRefPtr service = MakeAutoConnectableService();
2920 SetPowerState(PowerManagerProxyDelegate::kOn);
2921 SetPowerManager();
2922 EXPECT_CALL(*service, AutoConnect());
2923 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002924 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002925 dispatcher()->DispatchPendingEvents();
2926
mukesh agrawal784566d2012-08-08 18:32:58 -07002927 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002928 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2929 EXPECT_CALL(*service, AutoConnect());
2930 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002931 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002932
mukesh agrawal784566d2012-08-08 18:32:58 -07002933 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002934 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2935 EXPECT_CALL(*service, AutoConnect()).Times(0);
2936 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002937 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002938}
2939
Darin Petkov3ec55342012-09-28 14:04:44 +02002940TEST_F(ManagerTest, AddTerminationAction) {
2941 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002942 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002943 SetPowerManager();
2944 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2945 manager()->AddTerminationAction("action1", base::Closure());
2946 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2947 manager()->AddTerminationAction("action2", base::Closure());
2948}
2949
2950TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002951 const char kKey1[] = "action1";
2952 const char kKey2[] = "action2";
2953 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002954
2955 MockPowerManager &power_manager = *power_manager_;
2956 SetPowerManager();
2957
2958 // Removing an action when the hook table is empty should not result in any
2959 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002960 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002961 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2962 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2963 manager()->RemoveTerminationAction("unknown");
2964 Mock::VerifyAndClearExpectations(&power_manager);
2965
Daniel Eratf9753672013-01-24 10:17:02 -08002966 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2967 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002968 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002969 manager()->AddTerminationAction(kKey1, base::Closure());
2970 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2971 manager()->AddTerminationAction(kKey2, base::Closure());
2972
2973 // Removing an action that ends up with a non-empty hook table should not
2974 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002975 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002976 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2977 manager()->RemoveTerminationAction(kKey1);
2978 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2979 Mock::VerifyAndClearExpectations(&power_manager);
2980
2981 // Removing the last action should trigger unregistering from the power
2982 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002983 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2984 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002985 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2986 manager()->RemoveTerminationAction(kKey2);
2987 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2988}
2989
2990TEST_F(ManagerTest, RunTerminationActions) {
2991 TerminationActionTest test_action;
2992 const string kActionName = "action";
2993
2994 EXPECT_CALL(test_action, Done(_));
2995 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2996 test_action.AsWeakPtr()));
2997
2998 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2999 Bind(&TerminationActionTest::Action,
3000 test_action.AsWeakPtr()));
3001 test_action.set_manager(manager());
3002 EXPECT_CALL(test_action, Done(_));
3003 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
3004 test_action.AsWeakPtr()));
3005}
3006
Daniel Erat0818cca2012-12-14 10:16:21 -08003007TEST_F(ManagerTest, OnSuspendImminent) {
3008 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02003009 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08003010 EXPECT_CALL(*power_manager_,
3011 ReportSuspendReadiness(
3012 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003013 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003014 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02003015}
3016
3017TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08003018 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02003019 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08003020 EXPECT_CALL(*power_manager_,
3021 ReportSuspendReadiness(
3022 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003023 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003024 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02003025}
3026
Paul Stewartc681fa02012-03-02 19:40:04 -08003027TEST_F(ManagerTest, RecheckPortal) {
3028 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
3029 .WillOnce(Return(false));
3030 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
3031 .WillOnce(Return(true));
3032 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
3033 .Times(0);
3034
3035 manager()->RegisterDevice(mock_devices_[0]);
3036 manager()->RegisterDevice(mock_devices_[1]);
3037 manager()->RegisterDevice(mock_devices_[2]);
3038
3039 manager()->RecheckPortal(NULL);
3040}
3041
Paul Stewartd215af62012-04-24 23:25:50 -07003042TEST_F(ManagerTest, RecheckPortalOnService) {
3043 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
3044 dispatcher(),
3045 metrics(),
3046 manager());
3047 EXPECT_CALL(*mock_devices_[0].get(),
3048 IsConnectedToService(IsRefPtrTo(service)))
3049 .WillOnce(Return(false));
3050 EXPECT_CALL(*mock_devices_[1].get(),
3051 IsConnectedToService(IsRefPtrTo(service)))
3052 .WillOnce(Return(true));
3053 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
3054 .WillOnce(Return(true));
3055 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
3056 .Times(0);
3057
3058 manager()->RegisterDevice(mock_devices_[0]);
3059 manager()->RegisterDevice(mock_devices_[1]);
3060 manager()->RegisterDevice(mock_devices_[2]);
3061
3062 manager()->RecheckPortalOnService(service);
3063}
3064
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003065TEST_F(ManagerTest, GetDefaultService) {
3066 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003067 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003068
3069 scoped_refptr<MockService> mock_service(
3070 new NiceMock<MockService>(control_interface(),
3071 dispatcher(),
3072 metrics(),
3073 manager()));
3074
3075 manager()->RegisterService(mock_service);
3076 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003077 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003078
3079 scoped_refptr<MockConnection> mock_connection(
3080 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07003081 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003082 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003083 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003084
Paul Stewartce4ec192012-03-14 12:53:46 -07003085 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003086 manager()->DeregisterService(mock_service);
3087}
3088
Paul Stewart13ed2252012-03-21 12:52:46 -07003089TEST_F(ManagerTest, GetServiceWithGUID) {
3090 scoped_refptr<MockService> mock_service0(
3091 new NiceMock<MockService>(control_interface(),
3092 dispatcher(),
3093 metrics(),
3094 manager()));
3095
3096 scoped_refptr<MockService> mock_service1(
3097 new NiceMock<MockService>(control_interface(),
3098 dispatcher(),
3099 metrics(),
3100 manager()));
3101
Paul Stewartcb59fed2012-03-21 21:14:46 -07003102 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3103 .Times(0);
3104 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3105 .Times(0);
3106
Paul Stewart13ed2252012-03-21 12:52:46 -07003107 manager()->RegisterService(mock_service0);
3108 manager()->RegisterService(mock_service1);
3109
3110 const string kGUID0 = "GUID0";
3111 const string kGUID1 = "GUID1";
3112
3113 {
3114 Error error;
3115 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3116 EXPECT_FALSE(error.IsSuccess());
3117 EXPECT_FALSE(service);
3118 }
3119
3120 KeyValueStore args;
3121 args.SetString(flimflam::kGuidProperty, kGUID1);
3122
3123 {
3124 Error error;
3125 ServiceRefPtr service = manager()->GetService(args, &error);
3126 EXPECT_EQ(Error::kInvalidArguments, error.type());
3127 EXPECT_FALSE(service);
3128 }
3129
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003130 mock_service0->SetGuid(kGUID0, NULL);
3131 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003132
3133 {
3134 Error error;
3135 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3136 EXPECT_TRUE(error.IsSuccess());
3137 EXPECT_EQ(mock_service0.get(), service.get());
3138 }
3139
3140 {
3141 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003142 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3143 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003144 ServiceRefPtr service = manager()->GetService(args, &error);
3145 EXPECT_TRUE(error.IsSuccess());
3146 EXPECT_EQ(mock_service1.get(), service.get());
3147 }
3148
3149 manager()->DeregisterService(mock_service0);
3150 manager()->DeregisterService(mock_service1);
3151}
3152
Gary Morain028545d2012-04-07 14:55:52 -07003153
3154TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003155 EXPECT_FALSE(manager()->IsOnline());
3156 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3157
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003158 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003159 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003160 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3161 .Times(AnyNumber());
3162 scoped_refptr<MockService> mock_service0(
3163 new NiceMock<MockService>(control_interface(),
3164 dispatcher(),
3165 metrics(),
3166 manager()));
3167
3168 scoped_refptr<MockService> mock_service1(
3169 new NiceMock<MockService>(control_interface(),
3170 dispatcher(),
3171 metrics(),
3172 manager()));
3173
3174 EXPECT_CALL(*mock_service0.get(), IsConnected())
3175 .WillRepeatedly(Return(false));
3176 EXPECT_CALL(*mock_service1.get(), IsConnected())
3177 .WillRepeatedly(Return(false));
3178
3179 manager()->RegisterService(mock_service0);
3180 manager()->RegisterService(mock_service1);
3181
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003182 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003183 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3184
3185 manager()->DeregisterService(mock_service0);
3186 manager()->DeregisterService(mock_service1);
3187}
3188
3189TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003190 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003191 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003192 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3193 .Times(AnyNumber());
3194 scoped_refptr<MockService> mock_service0(
3195 new NiceMock<MockService>(control_interface(),
3196 dispatcher(),
3197 metrics(),
3198 manager()));
3199
3200 scoped_refptr<MockService> mock_service1(
3201 new NiceMock<MockService>(control_interface(),
3202 dispatcher(),
3203 metrics(),
3204 manager()));
3205
3206 EXPECT_CALL(*mock_service0.get(), IsConnected())
3207 .WillRepeatedly(Return(false));
3208 EXPECT_CALL(*mock_service1.get(), IsConnected())
3209 .WillRepeatedly(Return(true));
3210 EXPECT_CALL(*mock_service0.get(), state())
3211 .WillRepeatedly(Return(Service::kStateIdle));
3212 EXPECT_CALL(*mock_service1.get(), state())
3213 .WillRepeatedly(Return(Service::kStateConnected));
3214
3215 manager()->RegisterService(mock_service0);
3216 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003217 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003218
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003219 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003220 EXPECT_EQ("online", manager()->CalculateState(NULL));
3221
3222 manager()->DeregisterService(mock_service0);
3223 manager()->DeregisterService(mock_service1);
3224}
3225
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003226TEST_F(ManagerTest, StartupPortalList) {
3227 // Simulate loading value from the default profile.
3228 const string kProfileValue("wifi,vpn");
3229 manager()->props_.check_portal_list = kProfileValue;
3230
3231 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3232 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3233 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3234
3235 const string kStartupValue("cellular,ethernet");
3236 manager()->SetStartupPortalList(kStartupValue);
3237 // Ensure profile value is not overwritten, so when we save the default
3238 // profile, the correct value will still be written.
3239 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3240
3241 // However we should read back a different list.
3242 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3243 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3244 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3245
3246 const string kRuntimeValue("ppp");
3247 // Setting a runtime value over the control API should overwrite both
3248 // the profile value and what we read back.
3249 Error error;
3250 manager()->mutable_store()->SetStringProperty(
3251 flimflam::kCheckPortalListProperty,
3252 kRuntimeValue,
3253 &error);
3254 ASSERT_TRUE(error.IsSuccess());
3255 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3256 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3257 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3258 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3259}
3260
Paul Stewart036dba02012-08-07 12:34:41 -07003261TEST_F(ManagerTest, LinkMonitorEnabled) {
3262 const string kEnabledTechnologies("wifi,vpn");
3263 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3264 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3265 EXPECT_FALSE(
3266 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3267}
3268
Paul Stewart85aea152013-01-22 09:31:56 -08003269TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003270 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003271 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003272 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003273 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003274 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003275 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3276 AdoptProfile(manager(), profile);
3277 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3278 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3279 scoped_ptr<MockStore> store1(new MockStore);
3280 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3281}
3282
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003283TEST_F(ManagerTest, SetEnabledStateForTechnology) {
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003284 Error error(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003285 DisableTechnologyReplyHandler disable_technology_reply_handler;
3286 ResultCallback disable_technology_callback(
3287 Bind(&DisableTechnologyReplyHandler::ReportResult,
3288 disable_technology_reply_handler.AsWeakPtr()));
3289 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_)).Times(0);
3290
3291 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3292 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003293 EXPECT_TRUE(error.IsSuccess());
3294
Joshua Krollda798622012-06-05 12:30:48 -07003295 ON_CALL(*mock_devices_[0], technology())
3296 .WillByDefault(Return(Technology::kEthernet));
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003297 ON_CALL(*mock_devices_[1], technology())
3298 .WillByDefault(Return(Technology::kCellular));
3299 ON_CALL(*mock_devices_[2], technology())
3300 .WillByDefault(Return(Technology::kCellular));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003301
3302 manager()->RegisterDevice(mock_devices_[0]);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003303 manager()->RegisterDevice(mock_devices_[1]);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003304
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003305 // Ethernet Device is disabled, so disable succeeds immediately.
Arman Uguray2f352e62013-08-28 19:12:53 -07003306 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _))
3307 .WillOnce(WithArg<1>(Invoke(SetErrorSuccess)));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003308 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003309 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3310 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003311 EXPECT_TRUE(error.IsSuccess());
3312
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003313 // Ethernet Device is enabled, and mock doesn't change error from
3314 // kOperationInitiated, so expect disable to say operation in progress.
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003315 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3316 mock_devices_[0]->enabled_ = true;
3317 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003318 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3319 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003320 EXPECT_TRUE(error.IsOngoing());
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003321
3322 // Ethernet Device is disabled, and mock doesn't change error from
3323 // kOperationInitiated, so expect enable to say operation in progress.
3324 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3325 mock_devices_[0]->enabled_ = false;
3326 error.Populate(Error::kOperationInitiated);
3327 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, true,
3328 &error, disable_technology_callback);
3329 EXPECT_TRUE(error.IsOngoing());
3330
3331 // Cellular Device is enabled, but disable failed.
3332 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3333 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3334 mock_devices_[1]->enabled_ = true;
3335 error.Populate(Error::kOperationInitiated);
3336 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3337 &error, disable_technology_callback);
3338 EXPECT_EQ(Error::kPermissionDenied, error.type());
3339
3340 // Multiple Cellular Devices in enabled state. Should indicate IsOngoing
3341 // if one is in progress (even if the other completed immediately).
3342 manager()->RegisterDevice(mock_devices_[2]);
3343 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3344 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3345 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _));
3346 mock_devices_[1]->enabled_ = true;
3347 mock_devices_[2]->enabled_ = true;
3348 error.Populate(Error::kOperationInitiated);
3349 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3350 &error, disable_technology_callback);
3351 EXPECT_TRUE(error.IsOngoing());
3352
3353 // ...and order doesn't matter.
3354 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _));
3355 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3356 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3357 mock_devices_[1]->enabled_ = true;
3358 mock_devices_[2]->enabled_ = true;
3359 error.Populate(Error::kOperationInitiated);
3360 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3361 &error, disable_technology_callback);
3362 EXPECT_TRUE(error.IsOngoing());
3363 Mock::VerifyAndClearExpectations(&disable_technology_reply_handler);
3364
3365 // Multiple Cellular Devices in enabled state. Even if all disable
3366 // operations complete asynchronously, we only get one call to the
3367 // DisableTechnologyReplyHandler::ReportResult.
3368 ResultCallback device1_result_callback;
3369 ResultCallback device2_result_callback;
3370 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3371 .WillOnce(SaveArg<2>(&device1_result_callback));
3372 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3373 .WillOnce(DoAll(WithArg<1>(Invoke(SetErrorPermissionDenied)),
3374 SaveArg<2>(&device2_result_callback)));
3375 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_));
3376 mock_devices_[1]->enabled_ = true;
3377 mock_devices_[2]->enabled_ = true;
3378 error.Populate(Error::kOperationInitiated);
3379 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3380 &error, disable_technology_callback);
3381 EXPECT_TRUE(error.IsOngoing());
3382 device1_result_callback.Run(Error(Error::kSuccess));
3383 device2_result_callback.Run(Error(Error::kSuccess));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003384}
3385
Paul Stewart4d5efb72012-09-17 12:24:34 -07003386TEST_F(ManagerTest, IgnoredSearchList) {
3387 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003388 vector<string> ignored_paths;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003389 SetResolver(resolver.get());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003390
3391 const string kIgnored0 = "chromium.org";
3392 ignored_paths.push_back(kIgnored0);
3393 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003394 SetIgnoredDNSSearchPaths(kIgnored0, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003395 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3396
3397 const string kIgnored1 = "google.com";
3398 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3399 ignored_paths.push_back(kIgnored1);
3400 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003401 SetIgnoredDNSSearchPaths(kIgnoredSum, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003402 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3403
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003404 ignored_paths.clear();
3405 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3406 SetIgnoredDNSSearchPaths("", NULL);
3407 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3408
Paul Stewart4d5efb72012-09-17 12:24:34 -07003409 SetResolver(Resolver::GetInstance());
3410}
3411
Paul Stewartbfb82552012-10-24 16:48:48 -07003412TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3413 // Test to make sure that every service state-change causes the
3414 // Manager to emit a new service list.
3415 scoped_refptr<MockService> mock_service(
3416 new NiceMock<MockService>(control_interface(),
3417 dispatcher(),
3418 metrics(),
3419 manager()));
3420 EXPECT_CALL(*mock_service, state())
3421 .WillRepeatedly(Return(Service::kStateIdle));
3422
3423 manager()->RegisterService(mock_service);
3424 EXPECT_CALL(
3425 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3426 flimflam::kServicesProperty, _)).Times(1);
3427 EXPECT_CALL(
3428 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3429 flimflam::kServiceWatchListProperty, _)).Times(1);
3430 CompleteServiceSort();
3431
3432 Mock::VerifyAndClearExpectations(manager_adaptor_);
3433 EXPECT_CALL(
3434 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3435 flimflam::kServicesProperty, _)).Times(1);
3436 EXPECT_CALL(
3437 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3438 flimflam::kServiceWatchListProperty, _)).Times(1);
3439 manager()->UpdateService(mock_service.get());
3440 CompleteServiceSort();
3441
3442 manager()->DeregisterService(mock_service);
3443}
3444
3445TEST_F(ManagerTest, EnumerateServices) {
3446 scoped_refptr<MockService> mock_service(
3447 new NiceMock<MockService>(control_interface(),
3448 dispatcher(),
3449 metrics(),
3450 manager()));
3451 manager()->RegisterService(mock_service);
3452
3453 EXPECT_CALL(*mock_service, state())
3454 .WillRepeatedly(Return(Service::kStateConnected));
3455 EXPECT_CALL(*mock_service, IsVisible())
3456 .WillRepeatedly(Return(false));
3457 EXPECT_TRUE(EnumerateAvailableServices().empty());
3458 EXPECT_TRUE(EnumerateWatchedServices().empty());
3459
3460 EXPECT_CALL(*mock_service, state())
3461 .WillRepeatedly(Return(Service::kStateIdle));
3462 EXPECT_TRUE(EnumerateAvailableServices().empty());
3463 EXPECT_TRUE(EnumerateWatchedServices().empty());
3464
3465 EXPECT_CALL(*mock_service, IsVisible())
3466 .WillRepeatedly(Return(true));
3467 Service::ConnectState unwatched_states[] = {
3468 Service::kStateUnknown,
3469 Service::kStateIdle,
3470 Service::kStateFailure
3471 };
3472 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3473 EXPECT_CALL(*mock_service, state())
3474 .WillRepeatedly(Return(unwatched_states[i]));
3475 EXPECT_FALSE(EnumerateAvailableServices().empty());
3476 EXPECT_TRUE(EnumerateWatchedServices().empty());
3477 }
3478
3479 Service::ConnectState watched_states[] = {
3480 Service::kStateAssociating,
3481 Service::kStateConfiguring,
3482 Service::kStateConnected,
Paul Stewartbfb82552012-10-24 16:48:48 -07003483 Service::kStatePortal,
3484 Service::kStateOnline
3485 };
3486 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3487 EXPECT_CALL(*mock_service, state())
3488 .WillRepeatedly(Return(watched_states[i]));
3489 EXPECT_FALSE(EnumerateAvailableServices().empty());
3490 EXPECT_FALSE(EnumerateWatchedServices().empty());
3491 }
3492
3493 manager()->DeregisterService(mock_service);
3494}
3495
Paul Stewart39db5ca2013-03-18 14:15:17 -07003496TEST_F(ManagerTest, ConnectToBestServices) {
3497 scoped_refptr<MockService> wifi_service0(
3498 new NiceMock<MockService>(control_interface(),
3499 dispatcher(),
3500 metrics(),
3501 manager()));
3502 EXPECT_CALL(*wifi_service0.get(), state())
3503 .WillRepeatedly(Return(Service::kStateIdle));
3504 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3505 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003506 wifi_service0->SetConnectable(true);
3507 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003508 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3509 EXPECT_CALL(*wifi_service0.get(), technology())
3510 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003511 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3512 .WillRepeatedly(Return(false));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003513 EXPECT_CALL(*wifi_service0.get(), explicitly_disconnected())
3514 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003515
3516 scoped_refptr<MockService> wifi_service1(
3517 new NiceMock<MockService>(control_interface(),
3518 dispatcher(),
3519 metrics(),
3520 manager()));
3521 EXPECT_CALL(*wifi_service1.get(), state())
3522 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003523 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3524 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003525 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3526 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003527 wifi_service1->SetAutoConnect(true);
3528 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003529 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3530 EXPECT_CALL(*wifi_service1.get(), technology())
3531 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003532 EXPECT_CALL(*wifi_service1.get(), explicitly_disconnected())
3533 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003534
3535 scoped_refptr<MockService> wifi_service2(
3536 new NiceMock<MockService>(control_interface(),
3537 dispatcher(),
3538 metrics(),
3539 manager()));
3540 EXPECT_CALL(*wifi_service2.get(), state())
3541 .WillRepeatedly(Return(Service::kStateConnected));
3542 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3543 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003544 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3545 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003546 wifi_service2->SetAutoConnect(true);
3547 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003548 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3549 EXPECT_CALL(*wifi_service2.get(), technology())
3550 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003551 EXPECT_CALL(*wifi_service2.get(), explicitly_disconnected())
3552 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003553
3554 manager()->RegisterService(wifi_service0);
3555 manager()->RegisterService(wifi_service1);
3556 manager()->RegisterService(wifi_service2);
3557
3558 CompleteServiceSort();
3559 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3560
3561 scoped_refptr<MockService> cell_service(
3562 new NiceMock<MockService>(control_interface(),
3563 dispatcher(),
3564 metrics(),
3565 manager()));
3566
3567 EXPECT_CALL(*cell_service.get(), state())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003568 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003569 EXPECT_CALL(*cell_service.get(), IsConnected())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003570 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003571 EXPECT_CALL(*cell_service.get(), IsVisible())
3572 .WillRepeatedly(Return(true));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003573 cell_service->SetAutoConnect(true);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003574 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003575 EXPECT_CALL(*cell_service.get(), technology())
3576 .WillRepeatedly(Return(Technology::kCellular));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003577 EXPECT_CALL(*cell_service.get(), explicitly_disconnected())
3578 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003579 manager()->RegisterService(cell_service);
3580
Arman Uguray6fe4f262013-08-02 20:21:55 -07003581 scoped_refptr<MockService> wimax_service(
3582 new NiceMock<MockService>(control_interface(),
3583 dispatcher(),
3584 metrics(),
3585 manager()));
3586
3587 EXPECT_CALL(*wimax_service.get(), state())
3588 .WillRepeatedly(Return(Service::kStateConnected));
3589 EXPECT_CALL(*wimax_service.get(), IsConnected())
3590 .WillRepeatedly(Return(true));
3591 EXPECT_CALL(*wimax_service.get(), IsVisible())
3592 .WillRepeatedly(Return(true));
3593 wimax_service->SetAutoConnect(true);
3594 wimax_service->SetConnectable(true);
3595 EXPECT_CALL(*wimax_service.get(), technology())
3596 .WillRepeatedly(Return(Technology::kWiMax));
3597 EXPECT_CALL(*wimax_service.get(), explicitly_disconnected())
3598 .WillRepeatedly(Return(false));
3599 manager()->RegisterService(wimax_service);
3600
Paul Stewart39db5ca2013-03-18 14:15:17 -07003601 scoped_refptr<MockService> vpn_service(
3602 new NiceMock<MockService>(control_interface(),
3603 dispatcher(),
3604 metrics(),
3605 manager()));
3606
3607 EXPECT_CALL(*vpn_service.get(), state())
3608 .WillRepeatedly(Return(Service::kStateIdle));
3609 EXPECT_CALL(*vpn_service.get(), IsConnected())
3610 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003611 EXPECT_CALL(*vpn_service.get(), IsVisible())
3612 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003613 wifi_service2->SetAutoConnect(false);
3614 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003615 EXPECT_CALL(*vpn_service.get(), technology())
3616 .WillRepeatedly(Return(Technology::kVPN));
3617 manager()->RegisterService(vpn_service);
3618
3619 // The connected services should be at the top.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003620 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003621
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003622 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3623 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003624 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003625 EXPECT_CALL(*cell_service.get(), Connect(_, _))
3626 .Times(0); // Explicitly disconnected.
3627 EXPECT_CALL(*wimax_service.get(), Connect(_, _)).Times(0); // Is connected.
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003628 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003629
3630 manager()->ConnectToBestServices(NULL);
3631 dispatcher()->DispatchPendingEvents();
3632
3633 // After this operation, since the Connect calls above are mocked and
3634 // no actual state changes have occurred, we should expect that the
3635 // service sorting order will not have changed.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003636 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003637}
3638
Christopher Wiley83889862013-05-02 15:55:09 -07003639TEST_F(ManagerTest, VerifyWhenNotConnected) {
3640 const string kFakeCertificate("fake cert");
3641 const string kFakePublicKey("fake public key");
3642 const string kFakeNonce("fake public key");
3643 const string kFakeSignedData("fake signed data");
3644 const string kFakeUdn("fake udn");
3645 const vector<uint8_t> kSSID(10, 87);
3646 const string kConfiguredSSID("AConfiguredDestination");
3647 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3648 kConfiguredSSID.end());
3649 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
3650 scoped_refptr<MockWiFiService> mock_destination(
3651 new NiceMock<MockWiFiService>(control_interface(), dispatcher(),
3652 metrics(), manager(), wifi_provider_,
3653 kSSID, "", "none", false));
3654 // Register this service, but don't mark it as connected.
3655 manager()->RegisterService(mock_destination);
3656 // Verify that if we're not connected to anything, verification fails.
3657 {
3658 LOG(INFO) << "Can't verify if not connected.";
3659 EXPECT_CALL(*crypto_util_proxy_,
3660 VerifyDestination(_, _, _, _, _, _, _, _, _)).Times(0);
3661 Error error(Error::kOperationInitiated);
3662 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3663 kFakeSignedData, kFakeUdn, "", "",
3664 ResultBoolCallback(), &error);
3665 EXPECT_TRUE(error.IsFailure());
3666 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3667 }
3668 {
3669 // However, if the destination is already configured, we might be
3670 // connected to it via something other than WiFi, and we shouldn't
3671 // enforce the WiFi check.
3672 EXPECT_CALL(*crypto_util_proxy_,
3673 VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3674 kFakeSignedData, kFakeUdn,
3675 kConfiguredSSIDVector, kConfiguredBSSID,
3676 _, _)).Times(1).WillOnce(Return(true));
3677 Error error(Error::kOperationInitiated);
3678 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3679 kFakeSignedData, kFakeUdn, kConfiguredSSID,
3680 kConfiguredBSSID, ResultBoolCallback(),
3681 &error);
3682 EXPECT_FALSE(error.IsFailure());
3683 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3684 }
3685}
3686
Christopher Wiley1057cd72013-02-28 15:21:29 -08003687TEST_F(ManagerTest, VerifyDestination) {
3688 const string kFakeCertificate("fake cert");
3689 const string kFakePublicKey("fake public key");
3690 const string kFakeNonce("fake public key");
3691 const string kFakeSignedData("fake signed data");
3692 const string kFakeUdn("fake udn");
3693 const char kSSIDStr[] = "fake ssid";
3694 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
Christopher Wileycdde79f2013-05-01 14:26:56 -07003695 const string kConfiguredSSID("AConfiguredDestination");
3696 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3697 kConfiguredSSID.end());
3698 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
Christopher Wiley1057cd72013-02-28 15:21:29 -08003699 const string kFakeData("muffin man");
3700 scoped_refptr<MockWiFiService> mock_destination(
3701 new NiceMock<MockWiFiService>(control_interface(),
3702 dispatcher(),
3703 metrics(),
3704 manager(),
3705 wifi_provider_,
3706 kSSID,
3707 "",
3708 "none",
3709 false));
3710 manager()->RegisterService(mock_destination);
Christopher Wiley1057cd72013-02-28 15:21:29 -08003711 // Making the service look online will let service lookup in
3712 // VerifyDestinatoin succeed.
3713 EXPECT_CALL(*mock_destination.get(), IsConnected())
3714 .WillRepeatedly(Return(true));
Christopher Wiley83889862013-05-02 15:55:09 -07003715 StrictMock<DestinationVerificationTest> dv_test;
Christopher Wiley1057cd72013-02-28 15:21:29 -08003716
3717 // Lead off by verifying that the basic VerifyDestination flow works.
3718 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003719 LOG(INFO) << "Basic VerifyDestination flow.";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003720 ResultBoolCallback passed_down_callback;
3721 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3722 kFakePublicKey,
3723 kFakeNonce,
3724 kFakeSignedData,
3725 kFakeUdn,
3726 kSSID,
3727 _,
3728 _,
3729 _))
3730 .Times(1)
3731 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3732 // Ask the manager to verify the current destination. This should look
3733 // up our previously registered service, and pass some metadata about
3734 // that service down to the CryptoUtilProxy to verify.
3735 Error error(Error::kOperationInitiated);
3736 ResultBoolCallback cb = Bind(
3737 &DestinationVerificationTest::ResultBoolCallbackStub,
3738 dv_test.AsWeakPtr());
3739 manager()->VerifyDestination(kFakeCertificate,
3740 kFakePublicKey,
3741 kFakeNonce,
3742 kFakeSignedData,
3743 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003744 // Ask to be verified against that service.
3745 "", "",
3746 cb,
3747 &error);
3748 // We assert here, because if the operation is not ongoing, it is
3749 // inconsistent with shim behavior to call the callback anyway.
3750 ASSERT_TRUE(error.IsOngoing());
3751 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3752 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3753 // Call the callback passed into the CryptoUtilProxy, which
3754 // should find its way into the callback passed into the manager.
3755 // In real code, that callback passed into the manager is from the
3756 // DBus adaptor.
3757 Error e;
3758 passed_down_callback.Run(e, true);
3759 Mock::VerifyAndClearExpectations(&dv_test);
3760 }
3761
Christopher Wiley1057cd72013-02-28 15:21:29 -08003762 // Now for a slightly more complex variant. When we encrypt data,
3763 // we do the same verification step but monkey with the callback to
3764 // link ourselves to an encrypt step afterward.
3765 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003766 LOG(INFO) << "Basic VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003767 ResultBoolCallback passed_down_callback;
3768 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3769 kFakePublicKey,
3770 kFakeNonce,
3771 kFakeSignedData,
3772 kFakeUdn,
3773 kSSID,
3774 _,
3775 _,
3776 _))
3777 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3778
3779 Error error(Error::kOperationInitiated);
3780 ResultStringCallback cb = Bind(
3781 &DestinationVerificationTest::ResultStringCallbackStub,
3782 dv_test.AsWeakPtr());
3783 manager()->VerifyAndEncryptData(kFakeCertificate,
3784 kFakePublicKey,
3785 kFakeNonce,
3786 kFakeSignedData,
3787 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003788 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003789 kFakeData,
3790 cb,
3791 &error);
3792 ASSERT_TRUE(error.IsOngoing());
3793 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3794 // Now, if we call that passed down callback, we should see encrypt being
3795 // called.
3796 ResultStringCallback second_passed_down_callback;
3797 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3798 kFakeData,
3799 _,
3800 _))
3801 .Times(1)
3802 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3803 Return(true)));
3804 Error e;
3805 passed_down_callback.Run(e, true);
3806 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3807 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3808 // And if we call the second passed down callback, we should see the
3809 // original function we passed down to VerifyDestination getting called.
3810 e.Reset();
3811 second_passed_down_callback.Run(e, "");
3812 Mock::VerifyAndClearExpectations(&dv_test);
3813 }
3814
3815 // If verification fails on the way to trying to encrypt, we should ditch
3816 // without calling encrypt at all.
3817 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003818 LOG(INFO) << "Failed VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003819 ResultBoolCallback passed_down_callback;
3820 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3821 kFakePublicKey,
3822 kFakeNonce,
3823 kFakeSignedData,
3824 kFakeUdn,
3825 kSSID,
3826 _,
3827 _,
3828 _))
3829 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3830
3831 Error error(Error::kOperationInitiated);
3832 ResultStringCallback cb = Bind(
3833 &DestinationVerificationTest::ResultStringCallbackStub,
3834 dv_test.AsWeakPtr());
3835 manager()->VerifyAndEncryptData(kFakeCertificate,
3836 kFakePublicKey,
3837 kFakeNonce,
3838 kFakeSignedData,
3839 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003840 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003841 kFakeData,
3842 cb,
3843 &error);
3844 ASSERT_TRUE(error.IsOngoing());
3845 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3846 Error e(Error::kOperationFailed);
3847 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3848 // Although we're ditching, this callback is what cleans up the pending
3849 // DBus call.
3850 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3851 passed_down_callback.Run(e, false);
3852 Mock::VerifyAndClearExpectations(&dv_test);
3853 }
3854}
3855
Paul Stewartd2e1c362013-03-03 19:06:07 -08003856TEST_F(ManagerTest, IsProfileBefore) {
3857 scoped_refptr<MockProfile> profile0(
3858 new NiceMock<MockProfile>(
3859 control_interface(), metrics(), manager(), ""));
3860 scoped_refptr<MockProfile> profile1(
3861 new NiceMock<MockProfile>(
3862 control_interface(), metrics(), manager(), ""));
3863
3864 AdoptProfile(manager(), profile0);
3865 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3866 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3867 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3868
3869 // A few abnormal cases, but it's good to track their behavior.
3870 scoped_refptr<MockProfile> profile2(
3871 new NiceMock<MockProfile>(
3872 control_interface(), metrics(), manager(), ""));
3873 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3874 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3875 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3876 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3877}
3878
Paul Stewart967eaeb2013-04-25 19:53:07 -07003879TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
3880 MockStore storage0;
3881 MockStore storage1;
3882 MockStore storage2;
3883
3884 scoped_refptr<MockProfile> profile0(
3885 new NiceMock<MockProfile>(
3886 control_interface(), metrics(), manager(), ""));
3887 scoped_refptr<MockProfile> profile1(
3888 new NiceMock<MockProfile>(
3889 control_interface(), metrics(), manager(), ""));
3890 scoped_refptr<MockProfile> profile2(
3891 new NiceMock<MockProfile>(
3892 control_interface(), metrics(), manager(), ""));
3893
3894 AdoptProfile(manager(), profile0);
3895 AdoptProfile(manager(), profile1);
3896 AdoptProfile(manager(), profile2);
3897
3898 scoped_refptr<MockService> service(
3899 new NiceMock<MockService>(control_interface(),
3900 dispatcher(),
3901 metrics(),
3902 manager()));
3903
3904 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
3905 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
3906 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
3907
3908 const string kEntry0("aluminum_crutch");
3909 const string kEntry2("rehashed_faces");
3910
3911 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
3912 .WillOnce(Return(kEntry0));
3913 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
3914 .WillOnce(Return(""));
3915 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
3916 .WillOnce(Return(kEntry2));
3917
3918 const string kProfileRpc0("service_station");
3919 const string kProfileRpc2("crystal_tiaras");
3920
3921 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
3922 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
3923 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
3924
3925 map<string, string> entries =
3926 manager()->GetLoadableProfileEntriesForService(service);
3927 EXPECT_EQ(2, entries.size());
3928 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
3929 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
3930 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
3931 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
3932}
3933
mukesh agrawal00752532013-05-03 15:46:55 -07003934TEST_F(ManagerTest, InitializeProfilesInformsProviders) {
mukesh agrawald142fd62013-05-01 16:50:57 -07003935 // We need a real glib here, so that profiles are persisted.
3936 GLib glib;
3937 ScopedTempDir temp_dir;
3938 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3939 Manager manager(control_interface(),
3940 dispatcher(),
3941 metrics(),
3942 &glib,
3943 run_path(),
3944 storage_path(),
3945 temp_dir.path().value());
3946 // Can't use |wifi_provider_|, because it's owned by the Manager
3947 // object in the fixture.
3948 MockWiFiProvider *wifi_provider = new NiceMock<MockWiFiProvider>();
3949 manager.wifi_provider_.reset(wifi_provider); // pass ownership
Paul Stewartb87d22b2013-07-29 11:11:37 -07003950 manager.UpdateProviderMapping();
mukesh agrawald142fd62013-05-01 16:50:57 -07003951 // Give manager a valid place to write the user profile list.
3952 manager.user_profile_list_path_ = temp_dir.path().Append("user_profile_list");
3953
3954 // With no user profiles, the WiFiProvider should be called once
3955 // (for the default profile).
3956 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_));
3957 manager.InitializeProfiles();
3958 Mock::VerifyAndClearExpectations(wifi_provider);
3959
3960 // With |n| user profiles, the WiFiProvider should be called |n+1|
3961 // times. First, create 2 user profiles...
3962 const char kProfile0[] = "~user/profile0";
3963 const char kProfile1[] = "~user/profile1";
3964 string profile_rpc_path;
3965 Error error;
3966 manager.CreateProfile(kProfile0, &profile_rpc_path, &error);
3967 manager.PushProfile(kProfile0, &profile_rpc_path, &error);
3968 manager.CreateProfile(kProfile1, &profile_rpc_path, &error);
3969 manager.PushProfile(kProfile1, &profile_rpc_path, &error);
3970
3971 // ... then reset manager state ...
3972 manager.profiles_.clear();
3973
3974 // ...then check that the WiFiProvider is notified about all three
3975 // profiles (one default, two user).
3976 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_)).Times(3);
3977 manager.InitializeProfiles();
3978 Mock::VerifyAndClearExpectations(wifi_provider);
3979}
3980
mukesh agrawal00752532013-05-03 15:46:55 -07003981TEST_F(ManagerTest, InitializeProfilesHandlesDefaults) {
3982 // We need a real glib here, so that profiles are persisted.
3983 GLib glib;
3984 ScopedTempDir temp_dir;
3985 scoped_ptr<Manager> manager;
3986 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3987
3988 // Instantiate a Manager with empty persistent storage. Check that
3989 // defaults are set.
3990 //
3991 // Note that we use the same directory for default and user profiles.
3992 // This doesn't affect the test results, because we don't push a
3993 // user profile.
3994 manager.reset(new Manager(control_interface(),
3995 dispatcher(),
3996 metrics(),
3997 &glib,
3998 run_path(),
3999 temp_dir.path().value(),
4000 temp_dir.path().value()));
4001 manager->InitializeProfiles();
4002 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4003 manager->props_.check_portal_list);
4004 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
4005 manager->props_.ignored_dns_search_paths);
4006 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
4007 manager->props_.link_monitor_technologies);
4008 EXPECT_EQ(PortalDetector::kDefaultURL,
4009 manager->props_.portal_url);
4010 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
4011 manager->props_.portal_check_interval_seconds);
4012
4013 // Change one of the settings.
4014 static const string kCustomCheckPortalList = "fiber0";
4015 Error error;
4016 manager->SetCheckPortalList(kCustomCheckPortalList, &error);
4017 manager->profiles_[0]->Save();
4018
4019 // Instantiate a new manager. It should have our settings for
4020 // check_portal_list, rather than the default.
4021 manager.reset(new Manager(control_interface(),
4022 dispatcher(),
4023 metrics(),
4024 &glib,
4025 run_path(),
4026 temp_dir.path().value(),
4027 temp_dir.path().value()));
4028 manager->InitializeProfiles();
4029 EXPECT_EQ(kCustomCheckPortalList, manager->props_.check_portal_list);
4030
4031 // If we clear the persistent storage, we again get the default value.
4032 ASSERT_TRUE(temp_dir.Delete());
4033 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4034 manager.reset(new Manager(control_interface(),
4035 dispatcher(),
4036 metrics(),
4037 &glib,
4038 run_path(),
4039 temp_dir.path().value(),
4040 temp_dir.path().value()));
4041 manager->InitializeProfiles();
4042 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4043 manager->props_.check_portal_list);
4044}
4045
mukesh agrawalbebf1b82013-04-23 15:06:33 -07004046// Custom property setters should return false, and make no changes, if
4047// the new value is the same as the old value.
4048TEST_F(ManagerTest, CustomSetterNoopChange) {
4049 // SetCheckPortalList
4050 {
4051 static const string kCheckPortalList = "weird-device,weirder-device";
4052 Error error;
4053 // Set to known value.
4054 EXPECT_TRUE(SetCheckPortalList(kCheckPortalList, &error));
4055 EXPECT_TRUE(error.IsSuccess());
4056 // Set to same value.
4057 EXPECT_FALSE(SetCheckPortalList(kCheckPortalList, &error));
4058 EXPECT_TRUE(error.IsSuccess());
4059 }
4060
4061 // SetIgnoredDNSSearchPaths
4062 {
4063 NiceMock<MockResolver> resolver;
4064 static const string kIgnoredPaths = "example.com,example.org";
4065 Error error;
4066 SetResolver(&resolver);
4067 // Set to known value.
4068 EXPECT_CALL(resolver, set_ignored_search_list(_));
4069 EXPECT_TRUE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4070 EXPECT_TRUE(error.IsSuccess());
4071 Mock::VerifyAndClearExpectations(&resolver);
4072 // Set to same value.
4073 EXPECT_CALL(resolver, set_ignored_search_list(_)).Times(0);
4074 EXPECT_FALSE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4075 EXPECT_TRUE(error.IsSuccess());
4076 Mock::VerifyAndClearExpectations(&resolver);
4077 }
4078}
4079
Paul Stewart7de7e022013-08-28 09:42:50 -07004080TEST_F(ManagerTest, GeoLocation) {
4081 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4082
4083 auto device = make_scoped_refptr(new NiceMock<MockDevice>(control_interface(),
4084 dispatcher(),
4085 metrics(),
4086 manager(),
4087 "null",
4088 "addr",
4089 0));
4090
4091 // Manager should ignore gelocation info from technologies it does not know.
4092 EXPECT_CALL(*device, technology())
4093 .Times(AtLeast(1))
4094 .WillRepeatedly(Return(Technology::kEthernet));
4095 EXPECT_CALL(*device, GetGeolocationObjects()).Times(0);
4096 manager()->OnDeviceGeolocationInfoUpdated(device);
4097 Mock::VerifyAndClearExpectations(device);
4098 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4099
4100 // Manager should add WiFi geolocation info.
4101 EXPECT_CALL(*device, technology())
4102 .Times(AtLeast(1))
4103 .WillRepeatedly(Return(Technology::kWifi));
4104 EXPECT_CALL(*device, GetGeolocationObjects())
4105 .WillOnce(Return(vector<GeolocationInfo>()));
4106 manager()->OnDeviceGeolocationInfoUpdated(device);
4107 Mock::VerifyAndClearExpectations(device);
4108 auto location_infos = manager()->GetNetworksForGeolocation();
4109 EXPECT_EQ(1, location_infos.size());
4110 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4111
4112 // Manager should inclusively add cellular info.
4113 EXPECT_CALL(*device, technology())
4114 .Times(AtLeast(1))
4115 .WillRepeatedly(Return(Technology::kCellular));
4116 EXPECT_CALL(*device, GetGeolocationObjects())
4117 .WillOnce(Return(vector<GeolocationInfo>()));
4118 manager()->OnDeviceGeolocationInfoUpdated(device);
4119 location_infos = manager()->GetNetworksForGeolocation();
4120 EXPECT_EQ(2, location_infos.size());
4121 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4122 EXPECT_TRUE(ContainsKey(location_infos, kGeoCellTowersProperty));
4123}
4124
Chris Masone9be4a9d2011-05-16 15:44:09 -07004125} // namespace shill