blob: da17db719348474a92b77918c85a5b1706210fee [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"
mukesh agrawalb94adde2013-08-22 18:17:26 -070037#include "shill/mock_log.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000038#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020039#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070040#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070041#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070042#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070043#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080044#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070045#include "shill/mock_wifi_service.h"
mukesh agrawal00752532013-05-03 15:46:55 -070046#include "shill/portal_detector.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070047#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020048#include "shill/proxy_factory.h"
mukesh agrawal00752532013-05-03 15:46:55 -070049#include "shill/resolver.h"
Chris Masone6515aab2011-10-12 16:19:09 -070050#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070051#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020052#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070053
Christopher Wiley1057cd72013-02-28 15:21:29 -080054using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080055using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080056using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070057using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070058using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070059using std::string;
60using std::vector;
61
Chris Masone9be4a9d2011-05-16 15:44:09 -070062namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070063using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070064using ::testing::AnyNumber;
Paul Stewart7de7e022013-08-28 09:42:50 -070065using ::testing::AtLeast;
Gaurav Shah435de2c2011-11-17 19:01:07 -080066using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070067using ::testing::DoAll;
mukesh agrawalb94adde2013-08-22 18:17:26 -070068using ::testing::HasSubstr;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070069using ::testing::InSequence;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070070using ::testing::Invoke;
mukesh agrawal784566d2012-08-08 18:32:58 -070071using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070072using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070073using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070074using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070075using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070076using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070077using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080078using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080079using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080080using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070081using ::testing::Test;
mukesh agrawal46c27cc2013-07-10 16:39:10 -070082using ::testing::WithArg;
Chris Masone9be4a9d2011-05-16 15:44:09 -070083
Chris Masone3bd3c8c2011-06-13 08:20:26 -070084class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070085 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070086 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020087 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080088 device_info_(new NiceMock<MockDeviceInfo>(
89 control_interface(),
90 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080091 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080092 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080093 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070094 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080095 wifi_provider_(new NiceMock<MockWiFiProvider>()),
96 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
97 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070098 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
99 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800100 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700101 manager(),
102 "null0",
103 "addr0",
104 0));
105 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
106 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800107 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700108 manager(),
109 "null1",
110 "addr1",
111 1));
112 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
113 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800114 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700115 manager(),
116 "null2",
117 "addr2",
118 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800119 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
120 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800121 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800122 manager(),
123 "null3",
124 "addr3",
125 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700126 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800127 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800128
129 // Replace the manager's adaptor with a quieter one, and one
130 // we can do EXPECT*() against. Passes ownership.
131 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800132
Paul Stewart35eff132013-04-12 12:08:40 -0700133 // Replace the manager's Ethernet EAP provider with our mock.
134 // Passes ownership.
135 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
136
Paul Stewart3c504012013-01-17 17:49:58 -0800137 // Replace the manager's WiFi provider with our mock. Passes
138 // ownership.
139 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800140
Paul Stewartb87d22b2013-07-29 11:11:37 -0700141 // Update the manager's map from technology to provider.
142 manager()->UpdateProviderMapping();
143
Christopher Wiley1057cd72013-02-28 15:21:29 -0800144 // Replace the manager's crypto util proxy with our mock. Passes
145 // ownership.
146 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Paul Stewart9dd253e2013-04-22 08:32:59 -0700147
148 // Reset service serial number so service sorting by unique_name()
149 // (and by extension, sorting by order of creation) is predictable.
150 Service::serial_number_ = 10000;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700151 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700152 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700153
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100154 void SetMetrics(Metrics *metrics) {
155 manager()->set_metrics(metrics);
156 }
157
Paul Stewartfdd16072011-09-16 12:41:35 -0700158 bool IsDeviceRegistered(const DeviceRefPtr &device,
159 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700160 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700161 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700162 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700163 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700164 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700165
Paul Stewarta849a3d2011-11-03 05:54:09 -0700166 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
167 manager->profiles_.push_back(profile);
168 }
169
Paul Stewart63864b62012-11-07 15:10:55 -0800170 void SetRunning(bool running) {
171 manager()->running_ = running;
172 }
173
Paul Stewart75225512012-01-26 22:51:33 -0800174 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
175 return manager->ephemeral_profile_;
176 }
177
Paul Stewart307c2502013-03-23 12:32:10 -0700178 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
179 return manager->profiles_;
180 }
181
Chris Masone6515aab2011-10-12 16:19:09 -0700182 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
183 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700184 FilePath final_path(storage_path());
185 final_path = final_path.Append("test.profile");
186 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
187 storage->set_path(final_path);
188 if (!storage->Open())
189 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800190 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800191 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800192 manager,
193 id,
194 "",
195 false));
196 profile->set_storage(storage.release()); // Passes ownership of "storage".
197 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700198 }
199
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700200 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
201 const string &profile_identifier,
202 const string &service_name) {
203 GLib glib;
204 KeyFileStore store(&glib);
205 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
206 return store.Open() &&
207 store.SetString(service_name, "rather", "irrelevant") &&
208 store.Close();
209 }
210
211 Error::Type TestCreateProfile(Manager *manager, const string &name) {
212 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800213 string path;
214 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700215 return error.type();
216 }
217
218 Error::Type TestPopAnyProfile(Manager *manager) {
219 Error error;
220 manager->PopAnyProfile(&error);
221 return error.type();
222 }
223
Paul Stewart307c2502013-03-23 12:32:10 -0700224 Error::Type TestPopAllUserProfiles(Manager *manager) {
225 Error error;
226 manager->PopAllUserProfiles(&error);
227 return error.type();
228 }
229
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700230 Error::Type TestPopProfile(Manager *manager, const string &name) {
231 Error error;
232 manager->PopProfile(name, &error);
233 return error.type();
234 }
235
236 Error::Type TestPushProfile(Manager *manager, const string &name) {
237 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800238 string path;
239 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700240 return error.type();
241 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000242
Paul Stewartf3eced92013-04-17 12:18:22 -0700243 Error::Type TestInsertUserProfile(Manager *manager,
244 const string &name,
245 const string &user_hash) {
246 Error error;
247 string path;
248 manager->InsertUserProfile(name, user_hash, &path, &error);
249 return error.type();
250 }
251
Paul Stewartd2e1c362013-03-03 19:06:07 -0800252 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
253 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700254 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800255 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800256 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200257 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700258 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800259 return profile;
260 }
261
262 void AddMockProfileToManager(Manager *manager) {
263 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700264 }
265
Paul Stewartdfa46052012-06-26 09:44:14 -0700266 void CompleteServiceSort() {
267 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
268 dispatcher()->DispatchPendingEvents();
269 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
270 }
271
Paul Stewart49739c02012-08-08 17:24:03 -0700272 RpcIdentifier GetDefaultServiceRpcIdentifier() {
273 return manager()->GetDefaultServiceRpcIdentifier(NULL);
274 }
275
Paul Stewart4d5efb72012-09-17 12:24:34 -0700276 void SetResolver(Resolver *resolver) {
277 manager()->resolver_ = resolver;
278 }
279
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700280 bool SetIgnoredDNSSearchPaths(const string &search_paths, Error *error) {
281 return manager()->SetIgnoredDNSSearchPaths(search_paths, error);
282 }
283
284 bool SetCheckPortalList(const string &check_portal_list, Error *error) {
285 return manager()->SetCheckPortalList(check_portal_list, error);
Paul Stewart4d5efb72012-09-17 12:24:34 -0700286 }
287
288 const string &GetIgnoredDNSSearchPaths() {
289 return manager()->props_.ignored_dns_search_paths;
290 }
291
Paul Stewartd2e1c362013-03-03 19:06:07 -0800292 WiFiServiceRefPtr ReleaseTempMockService() {
293 // Take a reference to hold during this function.
294 WiFiServiceRefPtr temp_service = temp_mock_service_;
295 temp_mock_service_ = NULL;
296 return temp_service;
297 }
298
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700299 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000300 typedef scoped_refptr<MockService> MockServiceRefPtr;
301
Darin Petkova5e07ef2012-07-09 14:27:57 +0200302 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
303 public:
304 ServiceWatcher() {}
305 virtual ~ServiceWatcher() {}
306
307 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
308
309 private:
310 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
311 };
312
Darin Petkovca621542012-07-25 14:25:56 +0200313 class TestProxyFactory : public ProxyFactory {
314 public:
315 TestProxyFactory() {}
316
317 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
318 PowerManagerProxyDelegate */*delegate*/) {
319 return NULL;
320 }
321
322 private:
323 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
324 };
325
Darin Petkov3ec55342012-09-28 14:04:44 +0200326 class TerminationActionTest :
327 public base::SupportsWeakPtr<TerminationActionTest> {
328 public:
329 static const char kActionName[];
330
331 TerminationActionTest() : manager_(NULL) {}
332 virtual ~TerminationActionTest() {}
333
334 MOCK_METHOD1(Done, void(const Error &error));
335
336 void Action() {
337 manager_->TerminationActionComplete("action");
338 }
339
340 void set_manager(Manager *manager) { manager_ = manager; }
341
342 private:
343 Manager *manager_;
344 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
345 };
346
Christopher Wiley1057cd72013-02-28 15:21:29 -0800347 class DestinationVerificationTest :
348 public base::SupportsWeakPtr<DestinationVerificationTest> {
349 public:
350 DestinationVerificationTest() {}
351 virtual ~DestinationVerificationTest() {}
352
353 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
354 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
355 const string &value));
356 private:
357 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
358 };
359
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700360 class DisableTechnologyReplyHandler :
361 public base::SupportsWeakPtr<DisableTechnologyReplyHandler> {
362 public:
363 DisableTechnologyReplyHandler() {}
364 virtual ~DisableTechnologyReplyHandler() {}
365
366 MOCK_METHOD1(ReportResult, void(const Error &));
367
368 private:
369 DISALLOW_COPY_AND_ASSIGN(DisableTechnologyReplyHandler);
370 };
371
Darin Petkovca621542012-07-25 14:25:56 +0200372 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
373 power_manager_->power_state_ = state;
374 }
375
376 void SetPowerManager() {
377 manager()->set_power_manager(power_manager_.release());
378 }
379
Darin Petkov3ec55342012-09-28 14:04:44 +0200380 HookTable *GetTerminationActions() {
381 return &manager()->termination_actions_;
382 }
383
Darin Petkovca621542012-07-25 14:25:56 +0200384 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
385 manager()->OnPowerStateChanged(state);
386 }
387
Daniel Erat0818cca2012-12-14 10:16:21 -0800388 void OnSuspendImminent(int suspend_id) {
389 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200390 }
391
Daniel Erat0818cca2012-12-14 10:16:21 -0800392 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
393 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200394 }
395
Paul Stewartbfb82552012-10-24 16:48:48 -0700396 vector<string> EnumerateAvailableServices() {
397 return manager()->EnumerateAvailableServices(NULL);
398 }
399
400 vector<string> EnumerateWatchedServices() {
401 return manager()->EnumerateWatchedServices(NULL);
402 }
403
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000404 MockServiceRefPtr MakeAutoConnectableService() {
405 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
406 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800407 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000408 manager());
409 service->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700410 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000411 return service;
412 }
413
Paul Stewart35eff132013-04-12 12:08:40 -0700414 void SetEapProviderService(const ServiceRefPtr &service) {
415 ethernet_eap_provider_->set_service(service);
416 }
417
Darin Petkovca621542012-07-25 14:25:56 +0200418 TestProxyFactory proxy_factory_;
419 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700420 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800421 scoped_ptr<MockDeviceInfo> device_info_;
422
Paul Stewartd2e1c362013-03-03 19:06:07 -0800423 // This service is held for the manager, and given ownership in a mock
424 // function. This ensures that when the Manager takes ownership, there
425 // is only one reference left.
426 scoped_refptr<MockWiFiService> temp_mock_service_;
427
Paul Stewart3c504012013-01-17 17:49:58 -0800428 // These pointers are owned by the manager, and only tracked here for
429 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800430 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700431 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800432 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800433 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700434};
435
Darin Petkov3ec55342012-09-28 14:04:44 +0200436const char ManagerTest::TerminationActionTest::kActionName[] = "action";
437
Paul Stewart22aa71b2011-09-16 12:15:11 -0700438bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700439 if (!manager()->sort_services_task_.IsCancelled()) {
440 manager()->SortServicesTask();
441 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700442 return (svc0.get() == manager()->services_[0].get() &&
443 svc1.get() == manager()->services_[1].get());
444}
445
mukesh agrawal46c27cc2013-07-10 16:39:10 -0700446void SetErrorPermissionDenied(Error *error) {
447 error->Populate(Error::kPermissionDenied);
448}
449
Arman Uguray2f352e62013-08-28 19:12:53 -0700450void SetErrorSuccess(Error *error) {
451 error->Reset();
452}
453
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700454TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700455 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
456 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700457}
458
Chris Masone9be4a9d2011-05-16 15:44:09 -0700459TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700460 ON_CALL(*mock_devices_[0].get(), technology())
461 .WillByDefault(Return(Technology::kEthernet));
462 ON_CALL(*mock_devices_[1].get(), technology())
463 .WillByDefault(Return(Technology::kWifi));
464 ON_CALL(*mock_devices_[2].get(), technology())
465 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700466
Paul Stewart22aa71b2011-09-16 12:15:11 -0700467 manager()->RegisterDevice(mock_devices_[0]);
468 manager()->RegisterDevice(mock_devices_[1]);
469 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700470
Paul Stewart22aa71b2011-09-16 12:15:11 -0700471 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
472 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
473 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700474}
475
Paul Stewarta41e38d2011-11-11 07:47:29 -0800476TEST_F(ManagerTest, DeviceRegistrationAndStart) {
477 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500478 mock_devices_[0]->enabled_persistent_ = true;
479 mock_devices_[1]->enabled_persistent_ = false;
480 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800481 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500482 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800483 .Times(0);
484 manager()->RegisterDevice(mock_devices_[0]);
485 manager()->RegisterDevice(mock_devices_[1]);
486}
487
488TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800489 MockProfile *profile =
490 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800491 DeviceRefPtr device_ref(mock_devices_[0].get());
492 AdoptProfile(manager(), profile); // Passes ownership.
493 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200494 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800495 manager()->RegisterDevice(mock_devices_[0]);
496}
497
Chris Masone9be4a9d2011-05-16 15:44:09 -0700498TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700499 ON_CALL(*mock_devices_[0].get(), technology())
500 .WillByDefault(Return(Technology::kEthernet));
501 ON_CALL(*mock_devices_[1].get(), technology())
502 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700503
Gaurav Shah435de2c2011-11-17 19:01:07 -0800504 manager()->RegisterDevice(mock_devices_[0]);
505 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700506
Paul Stewart22aa71b2011-09-16 12:15:11 -0700507 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
508 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700509
Thieu Le5133b712013-02-19 14:47:21 -0800510 MockProfile *profile =
511 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700512 AdoptProfile(manager(), profile); // Passes ownership.
513
Eric Shienbrood9a245532012-03-07 14:20:39 -0500514 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700515 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800516 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700517 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700518
Eric Shienbrood9a245532012-03-07 14:20:39 -0500519 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700520 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800521 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700522 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700523}
524
525TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700526 // It's much easier and safer to use a real GLib for this test.
527 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700528 Manager manager(control_interface(),
529 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800530 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700531 &glib,
532 run_path(),
533 storage_path(),
534 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700535 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
536 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700537 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700538
Chris Masone9be4a9d2011-05-16 15:44:09 -0700539 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700540 new NiceMock<MockService>(control_interface(),
541 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800542 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700543 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700544 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700545 new NiceMock<MockService>(control_interface(),
546 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800547 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700548 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700549
Darin Petkov457728b2013-01-09 09:49:08 +0100550 string service1_name(mock_service->unique_name());
551 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700552
553 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
554 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700555 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700556 .WillRepeatedly(Return(service2_name));
Paul Stewartee6b3d72013-07-12 16:07:51 -0700557 // TODO(quiche): make this EXPECT_CALL work (crbug.com/203247)
Chris Masone9d779932011-08-25 16:33:41 -0700558 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700559 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700560
Chris Masone9d779932011-08-25 16:33:41 -0700561 manager.RegisterService(mock_service);
562 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700563
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800564 Error error;
565 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700566 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700567 EXPECT_EQ(2, ids.size());
568 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
569 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700570
Chris Masone9d779932011-08-25 16:33:41 -0700571 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
572 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
573
574 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700575}
576
Chris Masone6515aab2011-10-12 16:19:09 -0700577TEST_F(ManagerTest, RegisterKnownService) {
578 // It's much easier and safer to use a real GLib for this test.
579 GLib glib;
580 Manager manager(control_interface(),
581 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800582 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700583 &glib,
584 run_path(),
585 storage_path(),
586 string());
587 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
588 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700589 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700590 {
591 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
592 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800593 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700594 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700595 ASSERT_TRUE(profile->AdoptService(service1));
596 ASSERT_TRUE(profile->ContainsService(service1));
597 } // Force destruction of service1.
598
599 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
600 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800601 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700602 &manager));
603 manager.RegisterService(service2);
604 EXPECT_EQ(service2->profile().get(), profile.get());
605 manager.Stop();
606}
607
608TEST_F(ManagerTest, RegisterUnknownService) {
609 // It's much easier and safer to use a real GLib for this test.
610 GLib glib;
611 Manager manager(control_interface(),
612 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800613 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700614 &glib,
615 run_path(),
616 storage_path(),
617 string());
618 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
619 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700620 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700621 {
622 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
623 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800624 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700625 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700626 ASSERT_TRUE(profile->AdoptService(service1));
627 ASSERT_TRUE(profile->ContainsService(service1));
628 } // Force destruction of service1.
629 scoped_refptr<MockService> mock_service2(
630 new NiceMock<MockService>(control_interface(),
631 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800632 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700633 &manager));
634 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100635 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700636 manager.RegisterService(mock_service2);
637 EXPECT_NE(mock_service2->profile().get(), profile.get());
638 manager.Stop();
639}
640
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000641TEST_F(ManagerTest, DeregisterUnregisteredService) {
642 // WiFi assumes that it can deregister a service that is not
643 // registered. (E.g. a hidden service can be deregistered when it
644 // loses its last endpoint, and again when WiFi is Stop()-ed.)
645 //
646 // So test that doing so doesn't cause a crash.
647 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
648 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800649 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000650 manager());
651 manager()->DeregisterService(service);
652}
653
Chris Masonea8a2c252011-06-27 22:16:30 -0700654TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700655 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700656 map<string, ::DBus::Variant> props;
657 Error error(Error::kInvalidProperty, "");
658 {
659 ::DBus::Error dbus_error;
660 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700661 manager()->mutable_store()->SetStringProperty(
662 flimflam::kCheckPortalListProperty,
663 expected,
664 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700665 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700666 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
667 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
668 expected);
669 }
670 {
671 ::DBus::Error dbus_error;
672 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700673 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
674 expected,
675 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700676 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700677 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
678 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
679 expected);
680 }
681}
682
Chris Masone3c3f6a12011-07-01 10:01:41 -0700683TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700684 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800685 manager()->RegisterDevice(mock_devices_[0]);
686 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700687 {
688 map<string, ::DBus::Variant> props;
689 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700690 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700691 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700692 vector < ::DBus::Path> devices =
693 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700694 EXPECT_EQ(2, devices.size());
695 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700696}
697
mukesh agrawal2366eed2012-03-20 18:21:50 -0700698TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700699 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700700 map<string, ::DBus::Variant> props;
701 ::DBus::Error dbus_error;
702 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
703 map<string, ::DBus::Variant>::const_iterator prop =
704 props.find(flimflam::kServicesProperty);
705 ASSERT_FALSE(prop == props.end());
706 const ::DBus::Variant &variant = prop->second;
707 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
708}
709
Chris Masone6791a432011-07-12 13:23:19 -0700710TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700711 Manager manager(control_interface(),
712 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800713 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700714 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700715 run_path(),
716 storage_path(),
717 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700718 scoped_refptr<MockService> s2(new MockService(control_interface(),
719 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800720 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700721 &manager));
722 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700723 {
Chris Masone6515aab2011-10-12 16:19:09 -0700724 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700725 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800726 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700727 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700728 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700729 .WillRepeatedly(Return(true));
730 EXPECT_CALL(*storage, Flush())
731 .Times(AnyNumber())
732 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700733 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700734 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700735 }
Chris Masone6515aab2011-10-12 16:19:09 -0700736 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800737 ProfileRefPtr profile(
738 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700739 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700740
Chris Masone6515aab2011-10-12 16:19:09 -0700741 // Now, move the Service |s2| to another profile.
742 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
743 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700744
745 // Force destruction of the original Profile, to ensure that the Service
746 // is kept alive and populated with data.
747 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700748 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700749 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700750}
751
Paul Stewart7f61e522012-03-22 11:13:45 -0700752TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
753 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800754 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700755 const string kProfileName("profile0");
756 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
757 .WillRepeatedly(Return(kProfileName));
758 AdoptProfile(manager(), mock_profile);
759
760 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
761 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
762 EXPECT_EQ(mock_profile.get(), profile.get());
763}
764
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800765TEST_F(ManagerTest, SetProfileForService) {
766 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800767 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800768 string profile_name0("profile0");
769 EXPECT_CALL(*profile0, GetRpcIdentifier())
770 .WillRepeatedly(Return(profile_name0));
771 AdoptProfile(manager(), profile0);
772 scoped_refptr<MockService> service(new MockService(control_interface(),
773 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800774 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800775 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700776 EXPECT_FALSE(manager()->HasService(service));
777 {
778 Error error;
779 EXPECT_CALL(*profile0, AdoptService(_))
780 .WillOnce(Return(true));
781 // Expect that setting the profile of a service that does not already
782 // have one assigned does not cause a crash.
783 manager()->SetProfileForService(service, "profile0", &error);
784 EXPECT_TRUE(error.IsSuccess());
785 }
786
787 // The service should be registered as a side-effect of the profile being
788 // set for this service.
789 EXPECT_TRUE(manager()->HasService(service));
790
791 // Since we have mocked Profile::AdoptServie() above, the service's
792 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800793 service->set_profile(profile0);
794
795 {
796 Error error;
797 manager()->SetProfileForService(service, "foo", &error);
798 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700799 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800800 }
801
802 {
803 Error error;
804 manager()->SetProfileForService(service, profile_name0, &error);
805 EXPECT_EQ(Error::kInvalidArguments, error.type());
806 EXPECT_EQ("Service is already connected to this profile", error.message());
807 }
808
809 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800810 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800811 string profile_name1("profile1");
812 EXPECT_CALL(*profile1, GetRpcIdentifier())
813 .WillRepeatedly(Return(profile_name1));
814 AdoptProfile(manager(), profile1);
815
816 {
817 Error error;
818 EXPECT_CALL(*profile1, AdoptService(_))
819 .WillOnce(Return(true));
820 EXPECT_CALL(*profile0, AbandonService(_))
821 .WillOnce(Return(true));
822 manager()->SetProfileForService(service, profile_name1, &error);
823 EXPECT_TRUE(error.IsSuccess());
824 }
825}
826
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700827TEST_F(ManagerTest, CreateProfile) {
828 // It's much easier to use real Glib here since we want the storage
829 // side-effects.
830 GLib glib;
831 ScopedTempDir temp_dir;
832 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
833
834 Manager manager(control_interface(),
835 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800836 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700837 &glib,
838 run_path(),
839 storage_path(),
840 temp_dir.path().value());
841
842 // Invalid name should be rejected.
843 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
844
Paul Stewartd0a3b812012-03-28 22:48:22 -0700845 // A profile with invalid characters in it should similarly be rejected.
846 EXPECT_EQ(Error::kInvalidArguments,
847 TestCreateProfile(&manager, "valid_profile"));
848
849 // We should be able to create a machine profile.
850 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700851
Gary Morainb672d352012-04-25 09:19:06 -0700852 // We should succeed in creating a valid user profile. Verify the returned
853 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700854 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700855 {
856 Error error;
857 string path;
858 manager.CreateProfile(kProfile, &path, &error);
859 EXPECT_EQ(Error::kSuccess, error.type());
860 EXPECT_EQ("/profile_rpc", path);
861 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700862
863 // We should fail in creating it a second time (already exists).
864 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
865}
866
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700867// We receive PopProfile when a user logs out, and it should always trigger a
868// MemoryLog Clear() call.
869TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
870 GLib glib;
871 ScopedTempDir temp_dir;
872 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
873 Manager manager(control_interface(),
874 dispatcher(),
875 metrics(),
876 &glib,
877 run_path(),
878 storage_path(),
879 temp_dir.path().value());
880 const char kProfile0[] = "~user/profile0";
881 const char kPurgedMessage[] = "This message should be purged";
882 // Create a profile and push it on the stack, leave one uncreated
883 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
884 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
885
886 // Popping a profile which isn't on top should still clear the log.
887 LOG(INFO) << kPurgedMessage;
888 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
889 kPurgedMessage));
890 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
891 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
892 kPurgedMessage));
893
894 // Popping an invalid profile name should do the same thing.
895 LOG(INFO) << kPurgedMessage;
896 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
897 kPurgedMessage));
898 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
899 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
900 kPurgedMessage));
901
902 // Successful pops also purge the message log.
903 LOG(INFO) << kPurgedMessage;
904 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
905 kPurgedMessage));
906 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
907 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
908 kPurgedMessage));
909}
910
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700911TEST_F(ManagerTest, PushPopProfile) {
912 // It's much easier to use real Glib in creating a Manager for this
913 // test here since we want the storage side-effects.
914 GLib glib;
915 ScopedTempDir temp_dir;
916 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
917 Manager manager(control_interface(),
918 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800919 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700920 &glib,
921 run_path(),
922 storage_path(),
923 temp_dir.path().value());
924
925 // Pushing an invalid profile should fail.
926 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
927
Paul Stewartd0a3b812012-03-28 22:48:22 -0700928 // Pushing a default profile that does not exist should fail.
929 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700930
931 const char kProfile0[] = "~user/profile0";
932 const char kProfile1[] = "~user/profile1";
933
934 // Create a couple of profiles.
935 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
936 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
937
938 // Push these profiles on the stack.
939 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
940 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
941
942 // Pushing a profile a second time should fail.
943 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
944 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
945
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800946 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700947 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800948 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700949
950 // Make sure a profile name that doesn't exist fails.
951 const char kProfile2Id[] = "profile2";
952 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
953 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
954
955 // Create a new service, with a specific storage name.
956 scoped_refptr<MockService> service(
957 new NiceMock<MockService>(control_interface(),
958 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800959 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700960 &manager));
961 const char kServiceName[] = "service_storage_name";
962 EXPECT_CALL(*service.get(), GetStorageIdentifier())
963 .WillRepeatedly(Return(kServiceName));
964 EXPECT_CALL(*service.get(), Load(_))
965 .WillRepeatedly(Return(true));
966
967 // Add this service to the manager -- it should end up in the ephemeral
968 // profile.
969 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800970 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700971
972 // Create storage for a profile that contains the service storage name.
973 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
974 kServiceName));
975
976 // When we push the profile, the service should move away from the
977 // ephemeral profile to this new profile since it has an entry for
978 // this service.
979 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800980 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700981 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
982
983 // Insert another profile that should supersede ownership of the service.
984 const char kProfile3Id[] = "profile3";
985 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
986 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
987 kServiceName));
988 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
989 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
990
991 // Popping an invalid profile name should fail.
992 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
993
994 // Popping an profile that is not at the top of the stack should fail.
995 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
996
997 // Popping the top profile should succeed.
998 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
999
1000 // Moreover the service should have switched profiles to profile 2.
1001 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
1002
1003 // Popping the top profile should succeed.
1004 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1005
1006 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -08001007 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001008
1009 // Pop the remaining two services off the stack.
1010 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1011 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1012
1013 // Next pop should fail with "stack is empty".
1014 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -07001015
1016 const char kMachineProfile0[] = "machineprofile0";
1017 const char kMachineProfile1[] = "machineprofile1";
1018 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
1019 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
1020
1021 // Should be able to push a machine profile.
1022 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
1023
1024 // Should be able to push a user profile atop a machine profile.
1025 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1026
1027 // Pushing a system-wide profile on top of a user profile should fail.
1028 EXPECT_EQ(Error::kInvalidArguments,
1029 TestPushProfile(&manager, kMachineProfile1));
1030
1031 // However if we pop the user profile, we should be able stack another
1032 // machine profile on.
1033 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1034 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -07001035
1036 // Add two user profiles to the top of the stack.
1037 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1038 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
1039 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
1040 EXPECT_EQ(4, profiles.size());
1041
1042 // PopAllUserProfiles should remove both user profiles, leaving the two
1043 // machine profiles.
1044 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1045 EXPECT_EQ(2, profiles.size());
1046 EXPECT_TRUE(profiles[0]->GetUser().empty());
1047 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001048
1049 // Use InsertUserProfile() instead. Although a machine profile is valid
1050 // in this state, it cannot be added via InsertUserProfile.
1051 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1052 EXPECT_EQ(Error::kInvalidArguments,
1053 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1054 const char kUserHash0[] = "userhash0";
1055 const char kUserHash1[] = "userhash1";
1056 EXPECT_EQ(Error::kSuccess,
1057 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1058 EXPECT_EQ(Error::kSuccess,
1059 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1060 EXPECT_EQ(3, profiles.size());
1061 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1062 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001063}
1064
Paul Stewarte73d05c2012-03-29 16:26:05 -07001065TEST_F(ManagerTest, RemoveProfile) {
1066 // It's much easier to use real Glib in creating a Manager for this
1067 // test here since we want the storage side-effects.
1068 GLib glib;
1069 ScopedTempDir temp_dir;
1070 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1071 Manager manager(control_interface(),
1072 dispatcher(),
1073 metrics(),
1074 &glib,
1075 run_path(),
1076 storage_path(),
1077 temp_dir.path().value());
1078
1079 const char kProfile0[] = "profile0";
1080 FilePath profile_path(
1081 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1082
1083 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1084 ASSERT_TRUE(file_util::PathExists(profile_path));
1085
1086 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1087
1088 // Remove should fail since the profile is still on the stack.
1089 {
1090 Error error;
1091 manager.RemoveProfile(kProfile0, &error);
1092 EXPECT_EQ(Error::kInvalidArguments, error.type());
1093 }
1094
1095 // Profile path should still exist.
1096 EXPECT_TRUE(file_util::PathExists(profile_path));
1097
1098 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1099
1100 // This should succeed now that the profile is off the stack.
1101 {
1102 Error error;
1103 manager.RemoveProfile(kProfile0, &error);
1104 EXPECT_EQ(Error::kSuccess, error.type());
1105 }
1106
1107 // Profile path should no longer exist.
1108 EXPECT_FALSE(file_util::PathExists(profile_path));
1109
1110 // Another remove succeeds, due to a foible in file_util::Delete --
1111 // it is not an error to delete a file that does not exist.
1112 {
1113 Error error;
1114 manager.RemoveProfile(kProfile0, &error);
1115 EXPECT_EQ(Error::kSuccess, error.type());
1116 }
1117
1118 // Let's create an error case that will "work". Create a non-empty
1119 // directory in the place of the profile pathname.
1120 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1121 {
1122 Error error;
1123 manager.RemoveProfile(kProfile0, &error);
1124 EXPECT_EQ(Error::kOperationFailed, error.type());
1125 }
1126}
1127
Paul Stewartd3d03882013-08-29 15:43:42 -07001128TEST_F(ManagerTest, RemoveService) {
1129 MockServiceRefPtr mock_service(
1130 new NiceMock<MockService>(control_interface(),
1131 dispatcher(),
1132 metrics(),
1133 manager()));
1134
1135 // Used in expectations which cannot accept a mock refptr.
1136 const ServiceRefPtr &service = mock_service;
1137
1138 manager()->RegisterService(service);
1139 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1140
1141 scoped_refptr<MockProfile> profile(
1142 new StrictMock<MockProfile>(
1143 control_interface(), metrics(), manager(), ""));
1144 AdoptProfile(manager(), profile);
1145
1146 // If service is ephemeral, it should be unloaded and left ephemeral.
1147 EXPECT_CALL(*profile, AbandonService(service)).Times(0);
1148 EXPECT_CALL(*profile, ConfigureService(service)).Times(0);
1149 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(false));
1150 manager()->RemoveService(service);
1151 Mock::VerifyAndClearExpectations(mock_service);
1152 Mock::VerifyAndClearExpectations(profile);
1153 EXPECT_EQ(GetEphemeralProfile(manager()), service->profile().get());
1154 EXPECT_TRUE(manager()->HasService(service)); // Since Unload() was false.
1155
1156 // If service is not ephemeral and the Manager finds a profile to assign
1157 // the service to, the service should be re-parented. Note that since we
1158 // are using a MockProfile, ConfigureService() never actually changes the
1159 // Service's profile.
1160 service->set_profile(profile);
1161 EXPECT_CALL(*profile, AbandonService(service));
1162 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(true));
1163 EXPECT_CALL(*mock_service, Unload()).Times(0);
1164 manager()->RemoveService(service);
1165 Mock::VerifyAndClearExpectations(mock_service);
1166 Mock::VerifyAndClearExpectations(profile);
1167 EXPECT_TRUE(manager()->HasService(service));
1168 EXPECT_EQ(profile.get(), service->profile().get());
1169
1170 // If service becomes ephemeral since there is no profile to support it,
1171 // it should be unloaded.
1172 EXPECT_CALL(*profile, AbandonService(service));
1173 EXPECT_CALL(*profile, ConfigureService(service)).WillOnce(Return(false));
1174 EXPECT_CALL(*mock_service, Unload()).WillOnce(Return(true));
1175 manager()->RemoveService(service);
1176 EXPECT_FALSE(manager()->HasService(service));
1177}
1178
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001179TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1180 // It's much easier to use real Glib in creating a Manager for this
1181 // test here since we want the storage side-effects.
1182 GLib glib;
1183 ScopedTempDir temp_dir;
1184 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1185 Manager manager(control_interface(),
1186 dispatcher(),
1187 metrics(),
1188 &glib,
1189 run_path(),
1190 storage_path(),
1191 temp_dir.path().value());
1192
1193 const char kProfile0[] = "profile0";
1194 FilePath profile_path(
1195 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1196
1197 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1198 ASSERT_TRUE(file_util::PathExists(profile_path));
1199 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1200
1201 // Ensure that even if the backing filestore is removed, we still can't
1202 // create a profile twice.
1203 ASSERT_TRUE(file_util::Delete(profile_path, false));
1204 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1205}
1206
Paul Stewart75225512012-01-26 22:51:33 -08001207// Use this matcher instead of passing RefPtrs directly into the arguments
1208// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1209// system teardown.
1210MATCHER_P(IsRefPtrTo, ref_address, "") {
1211 return arg.get() == ref_address;
1212}
1213
1214TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1215 MockServiceRefPtr s_not_in_profile(
1216 new NiceMock<MockService>(control_interface(),
1217 dispatcher(),
1218 metrics(),
1219 manager()));
1220 MockServiceRefPtr s_not_in_group(
1221 new NiceMock<MockService>(control_interface(),
1222 dispatcher(),
1223 metrics(),
1224 manager()));
1225 MockServiceRefPtr s_configure_fail(
1226 new NiceMock<MockService>(control_interface(),
1227 dispatcher(),
1228 metrics(),
1229 manager()));
1230 MockServiceRefPtr s_configure_succeed(
1231 new NiceMock<MockService>(control_interface(),
1232 dispatcher(),
1233 metrics(),
1234 manager()));
1235
1236 string entry_name("entry_name");
1237 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1238 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1239 .WillRepeatedly(Return("not_entry_name"));
1240 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1241 .WillRepeatedly(Return(entry_name));
1242 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1243 .WillRepeatedly(Return(entry_name));
1244
1245 manager()->RegisterService(s_not_in_profile);
1246 manager()->RegisterService(s_not_in_group);
1247 manager()->RegisterService(s_configure_fail);
1248 manager()->RegisterService(s_configure_succeed);
1249
1250 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001251 new StrictMock<MockProfile>(
1252 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001253 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001254 new StrictMock<MockProfile>(
1255 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001256
1257 s_not_in_group->set_profile(profile1);
1258 s_configure_fail->set_profile(profile1);
1259 s_configure_succeed->set_profile(profile1);
1260
1261 AdoptProfile(manager(), profile0);
1262 AdoptProfile(manager(), profile1);
1263
1264 // No services are a member of this profile.
1265 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1266
1267 // No services that are members of this profile have this entry name.
1268 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1269
1270 // Only services that are members of the profile and group will be abandoned.
1271 EXPECT_CALL(*profile1.get(),
1272 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1273 EXPECT_CALL(*profile1.get(),
1274 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1275 EXPECT_CALL(*profile1.get(),
1276 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1277 .WillOnce(Return(true));
1278 EXPECT_CALL(*profile1.get(),
1279 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1280 .WillOnce(Return(true));
1281
1282 // Never allow services to re-join profile1.
1283 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1284 .WillRepeatedly(Return(false));
1285
1286 // Only allow one of the members of the profile and group to successfully
1287 // join profile0.
1288 EXPECT_CALL(*profile0.get(),
1289 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1290 EXPECT_CALL(*profile0.get(),
1291 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1292 EXPECT_CALL(*profile0.get(),
1293 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1294 .WillOnce(Return(false));
1295 EXPECT_CALL(*profile0.get(),
1296 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1297 .WillOnce(Return(true));
1298
1299 // Expect the failed-to-configure service to have Unload() called on it.
1300 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1301 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1302 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1303 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1304
1305 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1306
1307 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1308 EXPECT_EQ(profile1, s_not_in_group->profile());
1309 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1310
1311 // Since we are using a MockProfile, the profile does not actually change,
1312 // since ConfigureService was not actually called on the service.
1313 EXPECT_EQ(profile1, s_configure_succeed->profile());
1314}
1315
Paul Stewart65512e12012-03-26 18:01:08 -07001316TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1317 MockServiceRefPtr s_will_remove0(
1318 new NiceMock<MockService>(control_interface(),
1319 dispatcher(),
1320 metrics(),
1321 manager()));
1322 MockServiceRefPtr s_will_remove1(
1323 new NiceMock<MockService>(control_interface(),
1324 dispatcher(),
1325 metrics(),
1326 manager()));
1327 MockServiceRefPtr s_will_not_remove0(
1328 new NiceMock<MockService>(control_interface(),
1329 dispatcher(),
1330 metrics(),
1331 manager()));
1332 MockServiceRefPtr s_will_not_remove1(
1333 new NiceMock<MockService>(control_interface(),
1334 dispatcher(),
1335 metrics(),
1336 manager()));
1337
1338 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1339 .Times(4); // Once for each registration.
1340
1341 string entry_name("entry_name");
1342 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1343 .WillRepeatedly(Return(entry_name));
1344 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1345 .WillRepeatedly(Return(entry_name));
1346 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1347 .WillRepeatedly(Return(entry_name));
1348 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1349 .WillRepeatedly(Return(entry_name));
1350
1351 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001352 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001353 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001354 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001355 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001356 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001357 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001358 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001359
1360 // One for each service added above.
1361 ASSERT_EQ(4, manager()->services_.size());
1362
1363 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001364 new StrictMock<MockProfile>(
1365 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001366
1367 s_will_remove0->set_profile(profile);
1368 s_will_remove1->set_profile(profile);
1369 s_will_not_remove0->set_profile(profile);
1370 s_will_not_remove1->set_profile(profile);
1371
1372 AdoptProfile(manager(), profile);
1373
1374 // Deny any of the services re-entry to the profile.
1375 EXPECT_CALL(*profile, ConfigureService(_))
1376 .WillRepeatedly(Return(false));
1377
1378 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1379 .WillOnce(Return(true));
1380 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1381 .WillOnce(Return(true));
1382 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1383 .WillOnce(Return(true));
1384 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1385 .WillOnce(Return(true));
1386
1387 EXPECT_CALL(*s_will_remove0, Unload())
1388 .WillOnce(Return(true));
1389 EXPECT_CALL(*s_will_remove1, Unload())
1390 .WillOnce(Return(true));
1391 EXPECT_CALL(*s_will_not_remove0, Unload())
1392 .WillOnce(Return(false));
1393 EXPECT_CALL(*s_will_not_remove1, Unload())
1394 .WillOnce(Return(false));
1395
1396
1397 // This will cause all the profiles to be unloaded.
1398 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1399
1400 // 2 of the 4 services added above should have been unregistered and
1401 // removed, leaving 2.
1402 EXPECT_EQ(2, manager()->services_.size());
1403 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1404 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1405}
1406
1407TEST_F(ManagerTest, PopProfileWithUnload) {
1408 MockServiceRefPtr s_will_remove0(
1409 new NiceMock<MockService>(control_interface(),
1410 dispatcher(),
1411 metrics(),
1412 manager()));
1413 MockServiceRefPtr s_will_remove1(
1414 new NiceMock<MockService>(control_interface(),
1415 dispatcher(),
1416 metrics(),
1417 manager()));
1418 MockServiceRefPtr s_will_not_remove0(
1419 new NiceMock<MockService>(control_interface(),
1420 dispatcher(),
1421 metrics(),
1422 manager()));
1423 MockServiceRefPtr s_will_not_remove1(
1424 new NiceMock<MockService>(control_interface(),
1425 dispatcher(),
1426 metrics(),
1427 manager()));
1428
1429 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1430 .Times(5); // Once for each registration, and one after profile pop.
1431
1432 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001433 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001434 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001435 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001436 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001437 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001438 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001439 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001440
1441 // One for each service added above.
1442 ASSERT_EQ(4, manager()->services_.size());
1443
1444 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001445 new StrictMock<MockProfile>(
1446 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001447 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001448 new StrictMock<MockProfile>(
1449 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001450
1451 s_will_remove0->set_profile(profile1);
1452 s_will_remove1->set_profile(profile1);
1453 s_will_not_remove0->set_profile(profile1);
1454 s_will_not_remove1->set_profile(profile1);
1455
1456 AdoptProfile(manager(), profile0);
1457 AdoptProfile(manager(), profile1);
1458
1459 // Deny any of the services entry to profile0, so they will all be unloaded.
1460 EXPECT_CALL(*profile0, ConfigureService(_))
1461 .WillRepeatedly(Return(false));
1462
1463 EXPECT_CALL(*s_will_remove0, Unload())
1464 .WillOnce(Return(true));
1465 EXPECT_CALL(*s_will_remove1, Unload())
1466 .WillOnce(Return(true));
1467 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001468 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001469 EXPECT_CALL(*s_will_not_remove1, Unload())
1470 .WillOnce(Return(false));
1471
Philipp Neubeck79173602012-11-13 21:10:09 +01001472 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1473 // profile list.
1474 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1475 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1476
Paul Stewart65512e12012-03-26 18:01:08 -07001477 // This will pop profile1, which should cause all our profiles to unload.
1478 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001479 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001480
1481 // 2 of the 4 services added above should have been unregistered and
1482 // removed, leaving 2.
1483 EXPECT_EQ(2, manager()->services_.size());
1484 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1485 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001486
1487 // Expect the unloaded services to lose their profile reference.
1488 EXPECT_FALSE(s_will_remove0->profile());
1489 EXPECT_FALSE(s_will_remove1->profile());
1490
1491 // If we explicitly deregister a service, the effect should be the same
1492 // with respect to the profile reference.
1493 ASSERT_TRUE(s_will_not_remove0->profile());
1494 manager()->DeregisterService(s_will_not_remove0);
1495 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001496}
1497
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001498TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001499 {
1500 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001501 ::DBus::Variant offline_mode;
1502 offline_mode.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001503 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1504 flimflam::kOfflineModeProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001505 offline_mode,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001506 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001507 }
1508 {
1509 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001510 ::DBus::Variant country;
1511 country.writer().append_string("a_country");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001512 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1513 flimflam::kCountryProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001514 country,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001515 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001516 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001517 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001518 {
1519 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001520 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1521 flimflam::kCountryProperty,
1522 PropertyStoreTest::kBoolV,
1523 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001524 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001525 }
1526 {
1527 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001528 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1529 flimflam::kOfflineModeProperty,
1530 PropertyStoreTest::kStringV,
1531 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001532 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001533 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001534 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001535 {
1536 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001537 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001538 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001539 flimflam::kEnabledTechnologiesProperty,
1540 PropertyStoreTest::kStringsV,
1541 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001542 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001543 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001544}
1545
mukesh agrawal32399322011-09-01 10:53:43 -07001546TEST_F(ManagerTest, RequestScan) {
1547 {
1548 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001549 manager()->RegisterDevice(mock_devices_[0].get());
1550 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001551 EXPECT_CALL(*mock_devices_[0], technology())
1552 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001553 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _, _));
Joshua Krollda798622012-06-05 12:30:48 -07001554 EXPECT_CALL(*mock_devices_[1], technology())
1555 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie4823f4f2013-07-25 10:03:03 -07001556 EXPECT_CALL(*mock_devices_[1], Scan(_, _, _)).Times(0);
Wade Guthrie68d41092013-04-02 12:56:02 -07001557 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001558 }
1559
1560 {
1561 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001562 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001563 EXPECT_EQ(Error::kInvalidArguments, error.type());
1564 }
1565}
1566
Darin Petkovb65c2452012-02-23 15:17:06 +01001567TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001568 KeyValueStore args;
1569 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001570 manager()->GetService(args, &e);
1571 EXPECT_EQ(Error::kInvalidArguments, e.type());
1572 EXPECT_EQ("must specify service type", e.message());
1573}
1574
1575TEST_F(ManagerTest, GetServiceUnknownType) {
1576 KeyValueStore args;
1577 Error e;
1578 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1579 manager()->GetService(args, &e);
1580 EXPECT_EQ(Error::kNotSupported, e.type());
1581 EXPECT_EQ("service type is unsupported", e.message());
1582}
1583
Paul Stewart35eff132013-04-12 12:08:40 -07001584TEST_F(ManagerTest, GetServiceEthernetEap) {
1585 KeyValueStore args;
1586 Error e;
Paul Stewart55fc64c2013-07-18 09:51:35 -07001587 ServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1588 dispatcher(),
1589 metrics(),
1590 manager());
Paul Stewart35eff132013-04-12 12:08:40 -07001591 args.SetString(flimflam::kTypeProperty, kTypeEthernetEap);
1592 SetEapProviderService(service);
1593 EXPECT_EQ(service, manager()->GetService(args, &e));
1594 EXPECT_TRUE(e.IsSuccess());
1595}
1596
Darin Petkovb65c2452012-02-23 15:17:06 +01001597TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001598 KeyValueStore args;
1599 Error e;
1600 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001601 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001602 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001603 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001604 manager()->GetService(args, &e);
1605 EXPECT_TRUE(e.IsSuccess());
1606}
1607
Darin Petkov33af05c2012-02-28 10:10:30 +01001608TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1609 KeyValueStore args;
1610 Error e;
1611 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001612 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001613 new StrictMock<MockProfile>(
1614 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001615 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001616 ServiceRefPtr service = manager()->GetService(args, &e);
1617 EXPECT_EQ(Error::kNotSupported, e.type());
1618 EXPECT_FALSE(service);
1619}
1620
Darin Petkovb65c2452012-02-23 15:17:06 +01001621TEST_F(ManagerTest, GetServiceVPN) {
1622 KeyValueStore args;
1623 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001624 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001625 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001626 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001627 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001628 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001629 new StrictMock<MockProfile>(
1630 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001631 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001632
1633#if defined(DISABLE_VPN)
1634
1635 ServiceRefPtr service = manager()->GetService(args, &e);
1636 EXPECT_EQ(Error::kNotSupported, e.type());
1637 EXPECT_FALSE(service);
1638
1639#else
1640
Paul Stewart7f5ad572012-06-04 15:18:54 -07001641 ServiceRefPtr updated_service;
1642 EXPECT_CALL(*profile, UpdateService(_))
1643 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1644 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001645 EXPECT_CALL(*profile, LoadService(_))
1646 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001647 EXPECT_CALL(*profile, ConfigureService(_))
1648 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001649 ServiceRefPtr service = manager()->GetService(args, &e);
1650 EXPECT_TRUE(e.IsSuccess());
1651 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001652 EXPECT_EQ(service, updated_service);
1653 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001654
1655#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001656}
1657
Darin Petkovc63dcf02012-05-24 11:51:43 +02001658TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1659 KeyValueStore args;
1660 Error e;
1661 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1662 ServiceRefPtr service = manager()->GetService(args, &e);
1663 EXPECT_EQ(Error::kInvalidArguments, e.type());
1664 EXPECT_EQ("Missing WiMAX network id.", e.message());
1665 EXPECT_FALSE(service);
1666}
1667
Darin Petkovd1cd7972012-05-22 15:26:15 +02001668TEST_F(ManagerTest, GetServiceWiMax) {
1669 KeyValueStore args;
1670 Error e;
1671 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001672 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1673 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1674 ServiceRefPtr service = manager()->GetService(args, &e);
1675 EXPECT_TRUE(e.IsSuccess());
1676 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001677}
1678
Paul Stewart7f61e522012-03-22 11:13:45 -07001679TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1680 // Manager calls ActiveProfile() so we need at least one profile installed.
1681 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001682 new NiceMock<MockProfile>(
1683 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001684 AdoptProfile(manager(), profile);
1685
1686 KeyValueStore args;
1687 args.SetString(flimflam::kProfileProperty, "xxx");
1688 Error error;
1689 manager()->ConfigureService(args, &error);
1690 EXPECT_EQ(Error::kInvalidArguments, error.type());
1691 EXPECT_EQ("Invalid profile name xxx", error.message());
1692}
1693
1694TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1695 // Manager calls ActiveProfile() so we need at least one profile installed.
1696 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001697 new NiceMock<MockProfile>(
1698 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001699 AdoptProfile(manager(), profile);
1700
1701 KeyValueStore args;
1702 Error error;
1703 manager()->ConfigureService(args, &error);
1704 EXPECT_EQ(Error::kInvalidArguments, error.type());
1705 EXPECT_EQ("must specify service type", error.message());
1706}
1707
1708// A registered service in the ephemeral profile should be moved to the
1709// active profile as a part of configuration if no profile was explicitly
1710// specified.
1711TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1712 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001713 new NiceMock<MockProfile>(
1714 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001715
1716 AdoptProfile(manager(), profile); // This is now the active profile.
1717
Paul Stewartd2e1c362013-03-03 19:06:07 -08001718 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001719 scoped_refptr<MockWiFiService> service(
1720 new NiceMock<MockWiFiService>(control_interface(),
1721 dispatcher(),
1722 metrics(),
1723 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001724 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001725 ssid,
1726 "",
1727 "",
1728 false));
1729
1730 manager()->RegisterService(service);
1731 service->set_profile(GetEphemeralProfile(manager()));
1732
Paul Stewart3c504012013-01-17 17:49:58 -08001733 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001734 .WillOnce(Return(service));
1735 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1736 .WillOnce(Return(true));
1737 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1738 .WillOnce(Return(true));
1739
1740 KeyValueStore args;
1741 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1742 Error error;
1743 manager()->ConfigureService(args, &error);
1744 EXPECT_TRUE(error.IsSuccess());
1745}
1746
Paul Stewart2c575d22012-12-07 12:28:57 -08001747// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001748// specify a profile, it should be moved from the profile it was previously
1749// in to the specified profile if one was requested.
1750TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1751 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001752 new NiceMock<MockProfile>(
1753 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001754 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001755 new NiceMock<MockProfile>(
1756 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001757
1758 const string kProfileName0 = "profile0";
1759 const string kProfileName1 = "profile1";
1760
1761 EXPECT_CALL(*profile0, GetRpcIdentifier())
1762 .WillRepeatedly(Return(kProfileName0));
1763 EXPECT_CALL(*profile1, GetRpcIdentifier())
1764 .WillRepeatedly(Return(kProfileName1));
1765
1766 AdoptProfile(manager(), profile0);
1767 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1768
Paul Stewartd2e1c362013-03-03 19:06:07 -08001769 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001770 scoped_refptr<MockWiFiService> service(
1771 new NiceMock<MockWiFiService>(control_interface(),
1772 dispatcher(),
1773 metrics(),
1774 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001775 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001776 ssid,
1777 "",
1778 "",
1779 false));
1780
1781 manager()->RegisterService(service);
1782 service->set_profile(profile1);
1783
Paul Stewart3c504012013-01-17 17:49:58 -08001784 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001785 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001786 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1787 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001788 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1789 .WillOnce(Return(true));
1790 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1791 .WillOnce(Return(true));
1792 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1793 .WillOnce(Return(true));
1794
1795 KeyValueStore args;
1796 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1797 args.SetString(flimflam::kProfileProperty, kProfileName0);
1798 Error error;
1799 manager()->ConfigureService(args, &error);
1800 EXPECT_TRUE(error.IsSuccess());
1801 service->set_profile(NULL); // Breaks refcounting loop.
1802}
1803
Paul Stewart2c575d22012-12-07 12:28:57 -08001804// If we configure a service that is already a member of the specified
1805// profile, the Manager should not call LoadService or AdoptService again
1806// on this service.
1807TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1808 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001809 new NiceMock<MockProfile>(
1810 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001811
1812 const string kProfileName0 = "profile0";
1813
1814 EXPECT_CALL(*profile0, GetRpcIdentifier())
1815 .WillRepeatedly(Return(kProfileName0));
1816
1817 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1818
Paul Stewartd2e1c362013-03-03 19:06:07 -08001819 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001820 scoped_refptr<MockWiFiService> service(
1821 new NiceMock<MockWiFiService>(control_interface(),
1822 dispatcher(),
1823 metrics(),
1824 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001825 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001826 ssid,
1827 "",
1828 "",
1829 false));
1830
1831 manager()->RegisterService(service);
1832 service->set_profile(profile0);
1833
Paul Stewart3c504012013-01-17 17:49:58 -08001834 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001835 .WillOnce(Return(service));
1836 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1837 .Times(0);
1838 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1839 .WillOnce(Return(true));
1840 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1841 .Times(0);
1842
1843 KeyValueStore args;
1844 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1845 args.SetString(flimflam::kProfileProperty, kProfileName0);
1846 Error error;
1847 manager()->ConfigureService(args, &error);
1848 EXPECT_TRUE(error.IsSuccess());
1849 service->set_profile(NULL); // Breaks refcounting loop.
1850}
1851
Paul Stewart7f61e522012-03-22 11:13:45 -07001852// An unregistered service should remain unregistered, but its contents should
1853// be saved to the specified profile nonetheless.
1854TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1855 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001856 new NiceMock<MockProfile>(
1857 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001858 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001859 new NiceMock<MockProfile>(
1860 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001861
1862 const string kProfileName0 = "profile0";
1863 const string kProfileName1 = "profile1";
1864
1865 EXPECT_CALL(*profile0, GetRpcIdentifier())
1866 .WillRepeatedly(Return(kProfileName0));
1867 EXPECT_CALL(*profile1, GetRpcIdentifier())
1868 .WillRepeatedly(Return(kProfileName1));
1869
1870 AdoptProfile(manager(), profile0);
1871 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1872
Paul Stewartd2e1c362013-03-03 19:06:07 -08001873 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001874 scoped_refptr<MockWiFiService> service(
1875 new NiceMock<MockWiFiService>(control_interface(),
1876 dispatcher(),
1877 metrics(),
1878 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001879 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001880 ssid,
1881 "",
1882 "",
1883 false));
1884
1885 service->set_profile(profile1);
1886
Paul Stewart3c504012013-01-17 17:49:58 -08001887 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001888 .WillOnce(Return(service));
1889 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1890 .WillOnce(Return(true));
1891 EXPECT_CALL(*profile0, AdoptService(_))
1892 .Times(0);
1893 EXPECT_CALL(*profile1, AdoptService(_))
1894 .Times(0);
1895
1896 KeyValueStore args;
1897 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1898 args.SetString(flimflam::kProfileProperty, kProfileName0);
1899 Error error;
1900 manager()->ConfigureService(args, &error);
1901 EXPECT_TRUE(error.IsSuccess());
1902}
1903
Paul Stewartd2e1c362013-03-03 19:06:07 -08001904TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1905 KeyValueStore args;
1906 Error error;
1907 ServiceRefPtr service =
1908 manager()->ConfigureServiceForProfile("", args, &error);
Paul Stewart6ae05892013-07-29 12:21:12 -07001909 EXPECT_EQ(Error::kInvalidArguments, error.type());
1910 EXPECT_EQ("must specify service type", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001911 EXPECT_EQ(NULL, service.get());
1912}
1913
1914TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1915 KeyValueStore args;
1916 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1917 Error error;
1918 ServiceRefPtr service =
1919 manager()->ConfigureServiceForProfile("", args, &error);
1920 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07001921 EXPECT_EQ("service type is unsupported", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08001922 EXPECT_EQ(NULL, service.get());
1923}
1924
1925TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1926 KeyValueStore args;
1927 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1928 Error error;
1929 ServiceRefPtr service =
1930 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1931 EXPECT_EQ(Error::kNotFound, error.type());
1932 EXPECT_EQ("Profile specified was not found", error.message());
1933 EXPECT_EQ(NULL, service.get());
1934}
1935
1936TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1937 const string kProfileName0 = "profile0";
1938 const string kProfileName1 = "profile1";
1939 scoped_refptr<MockProfile> profile0(
1940 AddNamedMockProfileToManager(manager(), kProfileName0));
1941
1942 KeyValueStore args;
1943 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1944 args.SetString(flimflam::kProfileProperty, kProfileName1);
1945 Error error;
1946 ServiceRefPtr service =
1947 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1948 EXPECT_EQ(Error::kInvalidArguments, error.type());
1949 EXPECT_EQ("Profile argument does not match that in "
1950 "the configuration arguments", error.message());
1951 EXPECT_EQ(NULL, service.get());
1952}
1953
1954TEST_F(ManagerTest,
1955 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1956 const string kProfileName0 = "profile0";
1957 scoped_refptr<MockProfile> profile0(
1958 AddNamedMockProfileToManager(manager(), kProfileName0));
1959 KeyValueStore args;
1960 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1961 args.SetString(flimflam::kProfileProperty, kProfileName0);
1962
1963 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1964 .WillOnce(Return(WiFiServiceRefPtr()));
1965 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1966 .WillOnce(Return(WiFiServiceRefPtr()));
1967 Error error;
1968 ServiceRefPtr service =
1969 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1970 // Since we didn't set the error in the GetService expectation above...
1971 EXPECT_TRUE(error.IsSuccess());
1972 EXPECT_EQ(NULL, service.get());
1973}
1974
1975TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1976 const string kProfileName0 = "profile0";
1977 scoped_refptr<MockProfile> profile0(
1978 AddNamedMockProfileToManager(manager(), kProfileName0));
1979
1980 KeyValueStore args;
1981 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1982
1983 scoped_refptr<MockWiFiService> mock_service(
1984 new NiceMock<MockWiFiService>(control_interface(),
1985 dispatcher(),
1986 metrics(),
1987 manager(),
1988 wifi_provider_,
1989 vector<uint8_t>(),
1990 flimflam::kModeManaged,
1991 flimflam::kSecurityNone,
1992 false));
1993 ServiceRefPtr mock_service_generic(mock_service.get());
1994 mock_service->set_profile(profile0);
1995 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1996 .WillOnce(Return(WiFiServiceRefPtr()));
1997 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1998 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1999 .WillOnce(Return(true));
2000 Error error;
2001 ServiceRefPtr service =
2002 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2003 EXPECT_TRUE(error.IsSuccess());
2004 EXPECT_EQ(mock_service.get(), service.get());
2005 mock_service->set_profile(NULL); // Breaks reference cycle.
2006}
2007
2008TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
2009 scoped_refptr<MockService> mock_service(
2010 new NiceMock<MockService>(control_interface(),
2011 dispatcher(),
2012 metrics(),
2013 manager()));
2014 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002015 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08002016 manager()->RegisterService(mock_service);
2017 ServiceRefPtr mock_service_generic(mock_service.get());
2018
2019 const string kProfileName = "profile";
2020 scoped_refptr<MockProfile> profile(
2021 AddNamedMockProfileToManager(manager(), kProfileName));
2022 mock_service->set_profile(profile);
2023
2024 EXPECT_CALL(*mock_service, technology())
2025 .WillOnce(Return(Technology::kCellular))
2026 .WillOnce(Return(Technology::kWifi));
2027
2028 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
2029 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2030 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2031
2032 KeyValueStore args;
2033 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2034 args.SetString(flimflam::kGuidProperty, kGUID);
2035
2036 // The first attempt should fail because the service reports a technology
2037 // other than "WiFi".
2038 {
2039 Error error;
2040 ServiceRefPtr service =
2041 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2042 EXPECT_EQ(NULL, service.get());
2043 EXPECT_EQ(Error::kNotSupported, error.type());
Paul Stewart6ae05892013-07-29 12:21:12 -07002044 EXPECT_EQ("This GUID matches a non-wifi service", error.message());
Paul Stewartd2e1c362013-03-03 19:06:07 -08002045 }
2046
2047 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2048 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2049
2050 {
2051 Error error;
2052 ServiceRefPtr service =
2053 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2054 EXPECT_TRUE(error.IsSuccess());
2055 EXPECT_EQ(mock_service.get(), service.get());
2056 EXPECT_EQ(profile.get(), service->profile().get());
2057 }
2058 mock_service->set_profile(NULL); // Breaks reference cycle.
2059}
2060
2061TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
2062 const string kProfileName = "profile";
2063 scoped_refptr<MockProfile> profile(
2064 AddNamedMockProfileToManager(manager(), kProfileName));
2065
2066 scoped_refptr<MockWiFiService> mock_service(
2067 new NiceMock<MockWiFiService>(control_interface(),
2068 dispatcher(),
2069 metrics(),
2070 manager(),
2071 wifi_provider_,
2072 vector<uint8_t>(),
2073 flimflam::kModeManaged,
2074 flimflam::kSecurityNone,
2075 false));
2076 mock_service->set_profile(profile);
2077 ServiceRefPtr mock_service_generic(mock_service.get());
2078
2079 KeyValueStore args;
2080 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2081 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2082 .WillOnce(Return(mock_service));
2083 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2084 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
2085 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2086 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2087
2088 Error error;
2089 ServiceRefPtr service =
2090 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2091 EXPECT_TRUE(error.IsSuccess());
2092 EXPECT_EQ(mock_service.get(), service.get());
2093 EXPECT_EQ(profile.get(), service->profile().get());
2094 mock_service->set_profile(NULL); // Breaks reference cycle.
2095}
2096
2097TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2098 const string kProfileName = "profile";
2099 scoped_refptr<MockProfile> profile(
2100 AddNamedMockProfileToManager(manager(), kProfileName));
2101
2102 scoped_refptr<MockWiFiService> mock_service(
2103 new NiceMock<MockWiFiService>(control_interface(),
2104 dispatcher(),
2105 metrics(),
2106 manager(),
2107 wifi_provider_,
2108 vector<uint8_t>(),
2109 flimflam::kModeManaged,
2110 flimflam::kSecurityNone,
2111 false));
2112 mock_service->set_profile(GetEphemeralProfile(manager()));
2113 ServiceRefPtr mock_service_generic(mock_service.get());
2114
2115 KeyValueStore args;
2116 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2117 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2118 .WillOnce(Return(mock_service));
2119 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2120 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2121 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2122
2123 Error error;
2124 ServiceRefPtr service =
2125 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2126 EXPECT_TRUE(error.IsSuccess());
2127 EXPECT_EQ(mock_service.get(), service.get());
2128 EXPECT_EQ(profile.get(), service->profile().get());
2129 mock_service->set_profile(NULL); // Breaks reference cycle.
2130}
2131
2132TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2133 const string kProfileName0 = "profile0";
2134 scoped_refptr<MockProfile> profile0(
2135 AddNamedMockProfileToManager(manager(), kProfileName0));
2136 const string kProfileName1 = "profile1";
2137 scoped_refptr<MockProfile> profile1(
2138 AddNamedMockProfileToManager(manager(), kProfileName1));
2139
2140 scoped_refptr<MockWiFiService> mock_service(
2141 new NiceMock<MockWiFiService>(control_interface(),
2142 dispatcher(),
2143 metrics(),
2144 manager(),
2145 wifi_provider_,
2146 vector<uint8_t>(),
2147 flimflam::kModeManaged,
2148 flimflam::kSecurityNone,
2149 false));
2150 manager()->RegisterService(mock_service);
2151 mock_service->set_profile(profile0);
2152 ServiceRefPtr mock_service_generic(mock_service.get());
2153
2154 KeyValueStore args;
2155 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2156 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2157 .WillOnce(Return(mock_service));
2158 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2159 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2160 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2161 // This happens once to make the service loadable for the ConfigureService
2162 // below, and a second time after the service is modified.
2163 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2164 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2165 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2166 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2167
2168 Error error;
2169 ServiceRefPtr service =
2170 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2171 EXPECT_TRUE(error.IsSuccess());
2172 EXPECT_EQ(mock_service.get(), service.get());
2173 mock_service->set_profile(NULL); // Breaks reference cycle.
2174}
2175
2176TEST_F(ManagerTest,
2177 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2178 const string kProfileName0 = "profile0";
2179 scoped_refptr<MockProfile> profile0(
2180 AddNamedMockProfileToManager(manager(), kProfileName0));
2181 const string kProfileName1 = "profile1";
2182 scoped_refptr<MockProfile> profile1(
2183 AddNamedMockProfileToManager(manager(), kProfileName1));
2184
2185 scoped_refptr<MockWiFiService> matching_service(
2186 new StrictMock<MockWiFiService>(control_interface(),
2187 dispatcher(),
2188 metrics(),
2189 manager(),
2190 wifi_provider_,
2191 vector<uint8_t>(),
2192 flimflam::kModeManaged,
2193 flimflam::kSecurityNone,
2194 false));
2195 matching_service->set_profile(profile1);
2196
2197 // We need to get rid of our reference to this mock service as soon
2198 // as Manager::ConfigureServiceForProfile() takes a reference in its
2199 // call to WiFiProvider::CreateTemporaryService(). This way the
2200 // latter function can keep a DCHECK(service->HasOneRef() even in
2201 // unit tests.
2202 temp_mock_service_ =
2203 new NiceMock<MockWiFiService>(control_interface(),
2204 dispatcher(),
2205 metrics(),
2206 manager(),
2207 wifi_provider_,
2208 vector<uint8_t>(),
2209 flimflam::kModeManaged,
2210 flimflam::kSecurityNone,
2211 false);
2212
2213 // Only hold a pointer here so we don't affect the refcount.
2214 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2215
2216 KeyValueStore args;
2217 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2218 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2219 .WillOnce(Return(matching_service));
2220 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2221 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2222 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2223 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2224 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2225 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2226 .Times(1);
2227 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2228 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2229
2230 Error error;
2231 ServiceRefPtr service =
2232 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2233 EXPECT_TRUE(error.IsSuccess());
2234 EXPECT_EQ(NULL, service.get());
2235 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2236}
2237
Paul Stewart7a20aa42013-01-17 12:21:41 -08002238TEST_F(ManagerTest, FindMatchingService) {
2239 KeyValueStore args;
2240 {
2241 Error error;
2242 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2243 EXPECT_EQ(Error::kNotFound, error.type());
2244 }
2245
2246 scoped_refptr<MockService> mock_service0(
2247 new NiceMock<MockService>(control_interface(),
2248 dispatcher(),
2249 metrics(),
2250 manager()));
2251 scoped_refptr<MockService> mock_service1(
2252 new NiceMock<MockService>(control_interface(),
2253 dispatcher(),
2254 metrics(),
2255 manager()));
2256 manager()->RegisterService(mock_service0);
2257 manager()->RegisterService(mock_service1);
2258 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2259 .WillOnce(Return(true))
2260 .WillRepeatedly(Return(false));
2261 {
2262 Error error;
2263 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2264 EXPECT_TRUE(error.IsSuccess());
2265 }
2266 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2267 .WillOnce(Return(true))
2268 .WillRepeatedly(Return(false));
2269 {
2270 Error error;
2271 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2272 EXPECT_TRUE(error.IsSuccess());
2273 }
2274 {
2275 Error error;
2276 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2277 EXPECT_EQ(Error::kNotFound, error.type());
2278 }
2279}
2280
Paul Stewart22aa71b2011-09-16 12:15:11 -07002281TEST_F(ManagerTest, TechnologyOrder) {
2282 Error error;
2283 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2284 string(flimflam::kTypeWifi), &error);
2285 ASSERT_TRUE(error.IsSuccess());
2286 EXPECT_EQ(manager()->GetTechnologyOrder(),
2287 string(flimflam::kTypeEthernet) + "," +
2288 string(flimflam::kTypeWifi));
2289
2290 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2291 string(flimflam::kTypeWifi), &error);
2292 ASSERT_FALSE(error.IsSuccess());
2293 EXPECT_EQ(Error::kInvalidArguments, error.type());
2294 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2295 string(flimflam::kTypeWifi),
2296 manager()->GetTechnologyOrder());
2297}
2298
2299TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002300 // TODO(quiche): Some of these tests would probably fit better in
2301 // service_unittest, since the actual comparison of Services is
Paul Stewartee6b3d72013-07-12 16:07:51 -07002302 // implemented in Service. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002303
Paul Stewart22aa71b2011-09-16 12:15:11 -07002304 scoped_refptr<MockService> mock_service0(
2305 new NiceMock<MockService>(control_interface(),
2306 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002307 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002308 manager()));
2309 scoped_refptr<MockService> mock_service1(
2310 new NiceMock<MockService>(control_interface(),
2311 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002312 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002313 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002314
2315 manager()->RegisterService(mock_service0);
2316 manager()->RegisterService(mock_service1);
2317
Darin Petkov457728b2013-01-09 09:49:08 +01002318 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002319 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2320
2321 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002322 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002323 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2324
2325 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002326 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002327 manager()->UpdateService(mock_service1);
2328 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2329
2330 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002331 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002332 manager()->UpdateService(mock_service0);
2333 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2334
2335 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002336 EXPECT_CALL(*mock_service0.get(), technology())
2337 .WillRepeatedly(Return((Technology::kWifi)));
2338 EXPECT_CALL(*mock_service1.get(), technology())
2339 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002340
2341 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002342 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002343 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002344 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2345
2346 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2347 string(flimflam::kTypeEthernet), &error);
2348 EXPECT_TRUE(error.IsSuccess());
2349 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2350
Gaurav Shah435de2c2011-11-17 19:01:07 -08002351 // Priority.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002352 mock_service0->SetPriority(1, NULL);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002353 manager()->UpdateService(mock_service0);
2354 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2355
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002356 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002357 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002358 manager()->UpdateService(mock_service1);
2359 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2360
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002361 // Auto-connect.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002362 mock_service0->SetAutoConnect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002363 manager()->UpdateService(mock_service0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002364 mock_service1->SetAutoConnect(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002365 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002366 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2367
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002368 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2369 // to any of the others below, so we reset to the default state after
2370 // testing.
2371 EXPECT_CALL(*mock_service1.get(),
2372 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2373 .WillOnce(Return(true))
2374 .WillRepeatedly(Return(false));
2375 manager()->UpdateService(mock_service1);
2376 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2377 manager()->UpdateService(mock_service0);
2378 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2379
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002380 // Connectable.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002381 mock_service1->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002382 manager()->UpdateService(mock_service1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002383 mock_service0->SetConnectable(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002384 manager()->UpdateService(mock_service0);
2385 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2386
2387 // IsFailed.
2388 EXPECT_CALL(*mock_service0.get(), state())
2389 .WillRepeatedly(Return(Service::kStateIdle));
2390 EXPECT_CALL(*mock_service0.get(), IsFailed())
2391 .WillRepeatedly(Return(false));
2392 manager()->UpdateService(mock_service0);
2393 EXPECT_CALL(*mock_service0.get(), state())
2394 .WillRepeatedly(Return(Service::kStateFailure));
2395 EXPECT_CALL(*mock_service1.get(), IsFailed())
2396 .WillRepeatedly(Return(true));
2397 manager()->UpdateService(mock_service1);
2398 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2399
2400 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002401 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002402 .WillRepeatedly(Return(Service::kStateAssociating));
2403 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002404 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002405 manager()->UpdateService(mock_service1);
2406 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2407
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002408 // Connected.
2409 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002410 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002411 EXPECT_CALL(*mock_service0.get(), IsConnected())
2412 .WillRepeatedly(Return(true));
2413 manager()->UpdateService(mock_service0);
2414 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2415
Paul Stewarta121c442012-06-09 14:12:58 -07002416 // Portal.
2417 EXPECT_CALL(*mock_service1.get(), state())
2418 .WillRepeatedly(Return(Service::kStateConnected));
2419 EXPECT_CALL(*mock_service1.get(), IsConnected())
2420 .WillRepeatedly(Return(true));
2421 manager()->UpdateService(mock_service1);
2422 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2423
Paul Stewart22aa71b2011-09-16 12:15:11 -07002424 manager()->DeregisterService(mock_service0);
2425 manager()->DeregisterService(mock_service1);
2426}
2427
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002428TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002429 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002430 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002431
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002432 scoped_refptr<MockService> mock_service0(
2433 new NiceMock<MockService>(control_interface(),
2434 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002435 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002436 manager()));
2437 scoped_refptr<MockService> mock_service1(
2438 new NiceMock<MockService>(control_interface(),
2439 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002440 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002441 manager()));
2442
2443 scoped_refptr<MockConnection> mock_connection0(
2444 new NiceMock<MockConnection>(device_info_.get()));
2445 scoped_refptr<MockConnection> mock_connection1(
2446 new NiceMock<MockConnection>(device_info_.get()));
2447
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002448 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002449 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002450 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002451 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002452 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002453 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002454
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002455 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002456 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002457
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002458 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002459 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002460 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002461
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002462 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002463 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002464 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002465
Paul Stewartce4ec192012-03-14 12:53:46 -07002466 mock_service0->set_mock_connection(mock_connection0);
2467 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002468
2469 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002470 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002471 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002472
Darin Petkova5e07ef2012-07-09 14:27:57 +02002473 ServiceWatcher service_watcher;
2474 int tag =
2475 manager()->RegisterDefaultServiceCallback(
2476 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2477 service_watcher.AsWeakPtr()));
2478 EXPECT_EQ(1, tag);
2479
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002480 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002481 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2482 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002483 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002484 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002485 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002486
Darin Petkova5e07ef2012-07-09 14:27:57 +02002487 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002488 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002489 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002490 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002491 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002492 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002493 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002494
Paul Stewartce4ec192012-03-14 12:53:46 -07002495 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002496 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002497 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002498 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002499
2500 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002501 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002502}
2503
Darin Petkova5e07ef2012-07-09 14:27:57 +02002504TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2505 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2506 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2507
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002508 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002509 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002510
2511 scoped_refptr<MockService> mock_service(
2512 new NiceMock<MockService>(
2513 control_interface(), dispatcher(), metrics(), manager()));
2514 ServiceRefPtr service = mock_service;
2515 ServiceRefPtr null_service;
2516
2517 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2518 manager()->NotifyDefaultServiceChanged(null_service);
2519
2520 ServiceWatcher service_watcher1;
2521 ServiceWatcher service_watcher2;
2522 int tag1 =
2523 manager()->RegisterDefaultServiceCallback(
2524 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2525 service_watcher1.AsWeakPtr()));
2526 EXPECT_EQ(1, tag1);
2527 int tag2 =
2528 manager()->RegisterDefaultServiceCallback(
2529 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2530 service_watcher2.AsWeakPtr()));
2531 EXPECT_EQ(2, tag2);
2532
2533 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2534 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2535 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2536 manager()->NotifyDefaultServiceChanged(null_service);
2537
2538 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2539 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2540 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2541 manager()->NotifyDefaultServiceChanged(mock_service);
2542
2543 manager()->DeregisterDefaultServiceCallback(tag1);
2544 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2545 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2546 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2547 manager()->NotifyDefaultServiceChanged(mock_service);
2548 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2549
2550 manager()->DeregisterDefaultServiceCallback(tag2);
2551 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2552 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2553 manager()->NotifyDefaultServiceChanged(mock_service);
2554
2555 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2556 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2557}
2558
Gaurav Shah435de2c2011-11-17 19:01:07 -08002559TEST_F(ManagerTest, AvailableTechnologies) {
2560 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2561 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002562 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002563 manager(),
2564 "null4",
2565 "addr4",
2566 0));
2567 manager()->RegisterDevice(mock_devices_[0]);
2568 manager()->RegisterDevice(mock_devices_[1]);
2569 manager()->RegisterDevice(mock_devices_[2]);
2570 manager()->RegisterDevice(mock_devices_[3]);
2571
2572 ON_CALL(*mock_devices_[0].get(), technology())
2573 .WillByDefault(Return(Technology::kEthernet));
2574 ON_CALL(*mock_devices_[1].get(), technology())
2575 .WillByDefault(Return(Technology::kWifi));
2576 ON_CALL(*mock_devices_[2].get(), technology())
2577 .WillByDefault(Return(Technology::kCellular));
2578 ON_CALL(*mock_devices_[3].get(), technology())
2579 .WillByDefault(Return(Technology::kWifi));
2580
2581 set<string> expected_technologies;
2582 expected_technologies.insert(Technology::NameFromIdentifier(
2583 Technology::kEthernet));
2584 expected_technologies.insert(Technology::NameFromIdentifier(
2585 Technology::kWifi));
2586 expected_technologies.insert(Technology::NameFromIdentifier(
2587 Technology::kCellular));
2588 Error error;
2589 vector<string> technologies = manager()->AvailableTechnologies(&error);
2590
2591 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2592 ContainerEq(expected_technologies));
2593}
2594
2595TEST_F(ManagerTest, ConnectedTechnologies) {
2596 scoped_refptr<MockService> connected_service1(
2597 new NiceMock<MockService>(control_interface(),
2598 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002599 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002600 manager()));
2601 scoped_refptr<MockService> connected_service2(
2602 new NiceMock<MockService>(control_interface(),
2603 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002604 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002605 manager()));
2606 scoped_refptr<MockService> disconnected_service1(
2607 new NiceMock<MockService>(control_interface(),
2608 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002609 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002610 manager()));
2611 scoped_refptr<MockService> disconnected_service2(
2612 new NiceMock<MockService>(control_interface(),
2613 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002614 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002615 manager()));
2616
2617 ON_CALL(*connected_service1.get(), IsConnected())
2618 .WillByDefault(Return(true));
2619 ON_CALL(*connected_service2.get(), IsConnected())
2620 .WillByDefault(Return(true));
2621
2622 manager()->RegisterService(connected_service1);
2623 manager()->RegisterService(connected_service2);
2624 manager()->RegisterService(disconnected_service1);
2625 manager()->RegisterService(disconnected_service2);
2626
2627 manager()->RegisterDevice(mock_devices_[0]);
2628 manager()->RegisterDevice(mock_devices_[1]);
2629 manager()->RegisterDevice(mock_devices_[2]);
2630 manager()->RegisterDevice(mock_devices_[3]);
2631
2632 ON_CALL(*mock_devices_[0].get(), technology())
2633 .WillByDefault(Return(Technology::kEthernet));
2634 ON_CALL(*mock_devices_[1].get(), technology())
2635 .WillByDefault(Return(Technology::kWifi));
2636 ON_CALL(*mock_devices_[2].get(), technology())
2637 .WillByDefault(Return(Technology::kCellular));
2638 ON_CALL(*mock_devices_[3].get(), technology())
2639 .WillByDefault(Return(Technology::kWifi));
2640
2641 mock_devices_[0]->SelectService(connected_service1);
2642 mock_devices_[1]->SelectService(disconnected_service1);
2643 mock_devices_[2]->SelectService(disconnected_service2);
2644 mock_devices_[3]->SelectService(connected_service2);
2645
2646 set<string> expected_technologies;
2647 expected_technologies.insert(Technology::NameFromIdentifier(
2648 Technology::kEthernet));
2649 expected_technologies.insert(Technology::NameFromIdentifier(
2650 Technology::kWifi));
2651 Error error;
2652
2653 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2654 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2655 ContainerEq(expected_technologies));
2656}
2657
2658TEST_F(ManagerTest, DefaultTechnology) {
2659 scoped_refptr<MockService> connected_service(
2660 new NiceMock<MockService>(control_interface(),
2661 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002662 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002663 manager()));
2664 scoped_refptr<MockService> disconnected_service(
2665 new NiceMock<MockService>(control_interface(),
2666 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002667 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002668 manager()));
2669
2670 // Connected. WiFi.
2671 ON_CALL(*connected_service.get(), IsConnected())
2672 .WillByDefault(Return(true));
2673 ON_CALL(*connected_service.get(), state())
2674 .WillByDefault(Return(Service::kStateConnected));
2675 ON_CALL(*connected_service.get(), technology())
2676 .WillByDefault(Return(Technology::kWifi));
2677
2678 // Disconnected. Ethernet.
2679 ON_CALL(*disconnected_service.get(), technology())
2680 .WillByDefault(Return(Technology::kEthernet));
2681
2682 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002683 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002684 Error error;
2685 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2686
2687
2688 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002689 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002690 // Connected service should be brought to the front now.
2691 string expected_technology =
2692 Technology::NameFromIdentifier(Technology::kWifi);
2693 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2694}
2695
Paul Stewart212d60f2012-07-12 10:59:13 -07002696TEST_F(ManagerTest, Stop) {
2697 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002698 new NiceMock<MockProfile>(
2699 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002700 AdoptProfile(manager(), profile);
2701 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002702 new NiceMock<MockService>(control_interface(),
2703 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002704 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002705 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002706 manager()->RegisterService(service);
2707 manager()->RegisterDevice(mock_devices_[0]);
2708 EXPECT_CALL(*profile.get(),
2709 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2710 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002711 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002712 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2713 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002714 manager()->Stop();
2715}
2716
mukesh agrawal00917ce2011-11-22 23:56:55 +00002717TEST_F(ManagerTest, UpdateServiceConnected) {
2718 scoped_refptr<MockService> mock_service(
2719 new NiceMock<MockService>(control_interface(),
2720 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002721 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002722 manager()));
2723 manager()->RegisterService(mock_service);
2724 EXPECT_FALSE(mock_service->favorite());
2725 EXPECT_FALSE(mock_service->auto_connect());
2726
Gaurav Shah435de2c2011-11-17 19:01:07 -08002727 EXPECT_CALL(*mock_service.get(), IsConnected())
2728 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002729 manager()->UpdateService(mock_service);
2730 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2731 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002732 // SortServices test. (crbug.com/206367)
mukesh agrawal00917ce2011-11-22 23:56:55 +00002733 EXPECT_TRUE(mock_service->favorite());
2734 EXPECT_TRUE(mock_service->auto_connect());
2735}
2736
Thieu Led4e9e552012-02-16 16:26:07 -08002737TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2738 // This tests the case where the user connects to a service that is
2739 // currently associated with a profile. We want to make sure that the
2740 // favorite flag is set and that the flag is saved to the current
2741 // profile.
2742 scoped_refptr<MockService> mock_service(
2743 new NiceMock<MockService>(control_interface(),
2744 dispatcher(),
2745 metrics(),
2746 manager()));
2747 manager()->RegisterService(mock_service);
2748 EXPECT_FALSE(mock_service->favorite());
2749 EXPECT_FALSE(mock_service->auto_connect());
2750
Gary Moraind93615e2012-04-27 11:50:03 -07002751 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002752 new MockProfile(
2753 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002754
Gary Moraind93615e2012-04-27 11:50:03 -07002755 mock_service->set_profile(profile);
2756 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002757 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002758 EXPECT_CALL(*profile,
2759 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002760 manager()->UpdateService(mock_service);
2761 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2762 // to mock out MakeFavorite. And mocking that out would break the
Paul Stewartee6b3d72013-07-12 16:07:51 -07002763 // SortServices test. (crbug.com/206367)
Thieu Led4e9e552012-02-16 16:26:07 -08002764 EXPECT_TRUE(mock_service->favorite());
2765 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002766 // This releases the ref on the mock profile.
2767 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002768}
2769
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002770TEST_F(ManagerTest, SaveSuccessfulService) {
2771 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002772 new StrictMock<MockProfile>(
2773 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002774 AdoptProfile(manager(), profile);
2775 scoped_refptr<MockService> service(
2776 new NiceMock<MockService>(control_interface(),
2777 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002778 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002779 manager()));
2780
2781 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2782 ServiceRefPtr expect_service(service.get());
2783
2784 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2785 .WillOnce(Return(false));
2786 manager()->RegisterService(service);
2787
2788 EXPECT_CALL(*service.get(), state())
2789 .WillRepeatedly(Return(Service::kStateConnected));
2790 EXPECT_CALL(*service.get(), IsConnected())
2791 .WillRepeatedly(Return(true));
2792 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2793 .WillOnce(Return(true));
2794 manager()->UpdateService(service);
2795}
2796
Darin Petkove7c6ad32012-06-29 10:22:09 +02002797TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002798 MockProfile *profile0 =
2799 new MockProfile(control_interface(), metrics(), manager(), "");
2800 MockProfile *profile1 =
2801 new MockProfile(control_interface(), metrics(), manager(), "");
2802 MockProfile *profile2 =
2803 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002804 AdoptProfile(manager(), profile0); // Passes ownership.
2805 AdoptProfile(manager(), profile1); // Passes ownership.
2806 AdoptProfile(manager(), profile2); // Passes ownership.
2807 DeviceRefPtr device_ref(mock_devices_[0].get());
2808 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2809 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2810 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2811 manager()->UpdateDevice(mock_devices_[0]);
2812}
2813
Paul Stewart1b253142012-01-26 14:05:52 -08002814TEST_F(ManagerTest, EnumerateProfiles) {
2815 vector<string> profile_paths;
2816 for (size_t i = 0; i < 10; i++) {
2817 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002818 new StrictMock<MockProfile>(
2819 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002820 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002821 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2822 .WillOnce(Return(profile_paths.back()));
2823 AdoptProfile(manager(), profile);
2824 }
2825
2826 Error error;
2827 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2828 EXPECT_TRUE(error.IsSuccess());
2829 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2830 for (size_t i = 0; i < profile_paths.size(); i++) {
2831 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2832 }
2833}
2834
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002835TEST_F(ManagerTest, AutoConnectOnRegister) {
2836 MockServiceRefPtr service = MakeAutoConnectableService();
2837 EXPECT_CALL(*service.get(), AutoConnect());
2838 manager()->RegisterService(service);
2839 dispatcher()->DispatchPendingEvents();
2840}
2841
2842TEST_F(ManagerTest, AutoConnectOnUpdate) {
2843 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002844 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002845 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002846 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002847 manager()->RegisterService(service1);
2848 manager()->RegisterService(service2);
2849 dispatcher()->DispatchPendingEvents();
2850
2851 EXPECT_CALL(*service1.get(), AutoConnect());
2852 EXPECT_CALL(*service2.get(), state())
2853 .WillRepeatedly(Return(Service::kStateFailure));
2854 EXPECT_CALL(*service2.get(), IsFailed())
2855 .WillRepeatedly(Return(true));
2856 EXPECT_CALL(*service2.get(), IsConnected())
2857 .WillRepeatedly(Return(false));
2858 manager()->UpdateService(service2);
2859 dispatcher()->DispatchPendingEvents();
2860}
2861
2862TEST_F(ManagerTest, AutoConnectOnDeregister) {
2863 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002864 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002865 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002866 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002867 manager()->RegisterService(service1);
2868 manager()->RegisterService(service2);
2869 dispatcher()->DispatchPendingEvents();
2870
2871 EXPECT_CALL(*service1.get(), AutoConnect());
2872 manager()->DeregisterService(service2);
2873 dispatcher()->DispatchPendingEvents();
2874}
2875
Darin Petkov3ec55342012-09-28 14:04:44 +02002876TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2877 MockServiceRefPtr service = MakeAutoConnectableService();
2878 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2879 SetPowerManager();
2880 EXPECT_CALL(*service, AutoConnect()).Times(0);
2881 manager()->RegisterService(service);
2882 dispatcher()->DispatchPendingEvents();
2883}
2884
Darin Petkovca621542012-07-25 14:25:56 +02002885TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2886 MockServiceRefPtr service = MakeAutoConnectableService();
2887 SetPowerState(PowerManagerProxyDelegate::kMem);
2888 SetPowerManager();
2889 EXPECT_CALL(*service, AutoConnect()).Times(0);
2890 manager()->RegisterService(service);
2891 dispatcher()->DispatchPendingEvents();
2892}
2893
2894TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2895 MockServiceRefPtr service = MakeAutoConnectableService();
2896 SetPowerState(PowerManagerProxyDelegate::kOn);
2897 SetPowerManager();
2898 EXPECT_CALL(*service, AutoConnect());
2899 manager()->RegisterService(service);
2900 dispatcher()->DispatchPendingEvents();
2901}
2902
2903TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2904 MockServiceRefPtr service = MakeAutoConnectableService();
2905 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2906 SetPowerManager();
2907 EXPECT_CALL(*service, AutoConnect());
2908 manager()->RegisterService(service);
2909 dispatcher()->DispatchPendingEvents();
2910}
2911
Paul Stewart63864b62012-11-07 15:10:55 -08002912TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2913 SetRunning(false);
2914 MockServiceRefPtr service = MakeAutoConnectableService();
2915 EXPECT_CALL(*service, AutoConnect()).Times(0);
2916 manager()->RegisterService(service);
2917 dispatcher()->DispatchPendingEvents();
2918}
2919
Darin Petkovca621542012-07-25 14:25:56 +02002920TEST_F(ManagerTest, OnPowerStateChanged) {
2921 MockServiceRefPtr service = MakeAutoConnectableService();
2922 SetPowerState(PowerManagerProxyDelegate::kOn);
2923 SetPowerManager();
2924 EXPECT_CALL(*service, AutoConnect());
2925 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002926 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002927 dispatcher()->DispatchPendingEvents();
2928
mukesh agrawal784566d2012-08-08 18:32:58 -07002929 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002930 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2931 EXPECT_CALL(*service, AutoConnect());
2932 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002933 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002934
mukesh agrawal784566d2012-08-08 18:32:58 -07002935 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002936 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2937 EXPECT_CALL(*service, AutoConnect()).Times(0);
2938 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002939 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002940}
2941
Darin Petkov3ec55342012-09-28 14:04:44 +02002942TEST_F(ManagerTest, AddTerminationAction) {
2943 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002944 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002945 SetPowerManager();
2946 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2947 manager()->AddTerminationAction("action1", base::Closure());
2948 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2949 manager()->AddTerminationAction("action2", base::Closure());
2950}
2951
2952TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002953 const char kKey1[] = "action1";
2954 const char kKey2[] = "action2";
2955 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002956
2957 MockPowerManager &power_manager = *power_manager_;
2958 SetPowerManager();
2959
2960 // Removing an action when the hook table is empty should not result in any
2961 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002962 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002963 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2964 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2965 manager()->RemoveTerminationAction("unknown");
2966 Mock::VerifyAndClearExpectations(&power_manager);
2967
Daniel Eratf9753672013-01-24 10:17:02 -08002968 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2969 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002970 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002971 manager()->AddTerminationAction(kKey1, base::Closure());
2972 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2973 manager()->AddTerminationAction(kKey2, base::Closure());
2974
2975 // Removing an action that ends up with a non-empty hook table should not
2976 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002977 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002978 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2979 manager()->RemoveTerminationAction(kKey1);
2980 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2981 Mock::VerifyAndClearExpectations(&power_manager);
2982
2983 // Removing the last action should trigger unregistering from the power
2984 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002985 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2986 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002987 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2988 manager()->RemoveTerminationAction(kKey2);
2989 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2990}
2991
2992TEST_F(ManagerTest, RunTerminationActions) {
2993 TerminationActionTest test_action;
2994 const string kActionName = "action";
2995
2996 EXPECT_CALL(test_action, Done(_));
2997 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2998 test_action.AsWeakPtr()));
2999
3000 manager()->AddTerminationAction(TerminationActionTest::kActionName,
3001 Bind(&TerminationActionTest::Action,
3002 test_action.AsWeakPtr()));
3003 test_action.set_manager(manager());
3004 EXPECT_CALL(test_action, Done(_));
3005 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
3006 test_action.AsWeakPtr()));
3007}
3008
Daniel Erat0818cca2012-12-14 10:16:21 -08003009TEST_F(ManagerTest, OnSuspendImminent) {
3010 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02003011 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08003012 EXPECT_CALL(*power_manager_,
3013 ReportSuspendReadiness(
3014 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003015 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003016 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02003017}
3018
3019TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08003020 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02003021 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08003022 EXPECT_CALL(*power_manager_,
3023 ReportSuspendReadiness(
3024 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02003025 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08003026 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02003027}
3028
Paul Stewartc681fa02012-03-02 19:40:04 -08003029TEST_F(ManagerTest, RecheckPortal) {
3030 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
3031 .WillOnce(Return(false));
3032 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
3033 .WillOnce(Return(true));
3034 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
3035 .Times(0);
3036
3037 manager()->RegisterDevice(mock_devices_[0]);
3038 manager()->RegisterDevice(mock_devices_[1]);
3039 manager()->RegisterDevice(mock_devices_[2]);
3040
3041 manager()->RecheckPortal(NULL);
3042}
3043
Paul Stewartd215af62012-04-24 23:25:50 -07003044TEST_F(ManagerTest, RecheckPortalOnService) {
3045 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
3046 dispatcher(),
3047 metrics(),
3048 manager());
3049 EXPECT_CALL(*mock_devices_[0].get(),
3050 IsConnectedToService(IsRefPtrTo(service)))
3051 .WillOnce(Return(false));
3052 EXPECT_CALL(*mock_devices_[1].get(),
3053 IsConnectedToService(IsRefPtrTo(service)))
3054 .WillOnce(Return(true));
3055 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
3056 .WillOnce(Return(true));
3057 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
3058 .Times(0);
3059
3060 manager()->RegisterDevice(mock_devices_[0]);
3061 manager()->RegisterDevice(mock_devices_[1]);
3062 manager()->RegisterDevice(mock_devices_[2]);
3063
3064 manager()->RecheckPortalOnService(service);
3065}
3066
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003067TEST_F(ManagerTest, GetDefaultService) {
3068 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003069 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003070
3071 scoped_refptr<MockService> mock_service(
3072 new NiceMock<MockService>(control_interface(),
3073 dispatcher(),
3074 metrics(),
3075 manager()));
3076
3077 manager()->RegisterService(mock_service);
3078 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003079 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003080
3081 scoped_refptr<MockConnection> mock_connection(
3082 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07003083 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003084 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07003085 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003086
Paul Stewartce4ec192012-03-14 12:53:46 -07003087 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07003088 manager()->DeregisterService(mock_service);
3089}
3090
Paul Stewart13ed2252012-03-21 12:52:46 -07003091TEST_F(ManagerTest, GetServiceWithGUID) {
3092 scoped_refptr<MockService> mock_service0(
3093 new NiceMock<MockService>(control_interface(),
3094 dispatcher(),
3095 metrics(),
3096 manager()));
3097
3098 scoped_refptr<MockService> mock_service1(
3099 new NiceMock<MockService>(control_interface(),
3100 dispatcher(),
3101 metrics(),
3102 manager()));
3103
Paul Stewartcb59fed2012-03-21 21:14:46 -07003104 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3105 .Times(0);
3106 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3107 .Times(0);
3108
Paul Stewart13ed2252012-03-21 12:52:46 -07003109 manager()->RegisterService(mock_service0);
3110 manager()->RegisterService(mock_service1);
3111
3112 const string kGUID0 = "GUID0";
3113 const string kGUID1 = "GUID1";
3114
3115 {
3116 Error error;
3117 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3118 EXPECT_FALSE(error.IsSuccess());
3119 EXPECT_FALSE(service);
3120 }
3121
3122 KeyValueStore args;
3123 args.SetString(flimflam::kGuidProperty, kGUID1);
3124
3125 {
3126 Error error;
3127 ServiceRefPtr service = manager()->GetService(args, &error);
3128 EXPECT_EQ(Error::kInvalidArguments, error.type());
3129 EXPECT_FALSE(service);
3130 }
3131
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003132 mock_service0->SetGuid(kGUID0, NULL);
3133 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003134
3135 {
3136 Error error;
3137 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3138 EXPECT_TRUE(error.IsSuccess());
3139 EXPECT_EQ(mock_service0.get(), service.get());
3140 }
3141
3142 {
3143 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003144 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3145 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003146 ServiceRefPtr service = manager()->GetService(args, &error);
3147 EXPECT_TRUE(error.IsSuccess());
3148 EXPECT_EQ(mock_service1.get(), service.get());
3149 }
3150
3151 manager()->DeregisterService(mock_service0);
3152 manager()->DeregisterService(mock_service1);
3153}
3154
Gary Morain028545d2012-04-07 14:55:52 -07003155
3156TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003157 EXPECT_FALSE(manager()->IsOnline());
3158 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3159
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003160 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003161 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003162 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3163 .Times(AnyNumber());
3164 scoped_refptr<MockService> mock_service0(
3165 new NiceMock<MockService>(control_interface(),
3166 dispatcher(),
3167 metrics(),
3168 manager()));
3169
3170 scoped_refptr<MockService> mock_service1(
3171 new NiceMock<MockService>(control_interface(),
3172 dispatcher(),
3173 metrics(),
3174 manager()));
3175
3176 EXPECT_CALL(*mock_service0.get(), IsConnected())
3177 .WillRepeatedly(Return(false));
3178 EXPECT_CALL(*mock_service1.get(), IsConnected())
3179 .WillRepeatedly(Return(false));
3180
3181 manager()->RegisterService(mock_service0);
3182 manager()->RegisterService(mock_service1);
3183
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003184 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003185 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3186
3187 manager()->DeregisterService(mock_service0);
3188 manager()->DeregisterService(mock_service1);
3189}
3190
3191TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003192 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003193 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003194 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3195 .Times(AnyNumber());
3196 scoped_refptr<MockService> mock_service0(
3197 new NiceMock<MockService>(control_interface(),
3198 dispatcher(),
3199 metrics(),
3200 manager()));
3201
3202 scoped_refptr<MockService> mock_service1(
3203 new NiceMock<MockService>(control_interface(),
3204 dispatcher(),
3205 metrics(),
3206 manager()));
3207
3208 EXPECT_CALL(*mock_service0.get(), IsConnected())
3209 .WillRepeatedly(Return(false));
3210 EXPECT_CALL(*mock_service1.get(), IsConnected())
3211 .WillRepeatedly(Return(true));
3212 EXPECT_CALL(*mock_service0.get(), state())
3213 .WillRepeatedly(Return(Service::kStateIdle));
3214 EXPECT_CALL(*mock_service1.get(), state())
3215 .WillRepeatedly(Return(Service::kStateConnected));
3216
3217 manager()->RegisterService(mock_service0);
3218 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003219 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003220
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003221 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003222 EXPECT_EQ("online", manager()->CalculateState(NULL));
3223
3224 manager()->DeregisterService(mock_service0);
3225 manager()->DeregisterService(mock_service1);
3226}
3227
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003228TEST_F(ManagerTest, StartupPortalList) {
3229 // Simulate loading value from the default profile.
3230 const string kProfileValue("wifi,vpn");
3231 manager()->props_.check_portal_list = kProfileValue;
3232
3233 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3234 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3235 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3236
3237 const string kStartupValue("cellular,ethernet");
3238 manager()->SetStartupPortalList(kStartupValue);
3239 // Ensure profile value is not overwritten, so when we save the default
3240 // profile, the correct value will still be written.
3241 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3242
3243 // However we should read back a different list.
3244 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3245 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3246 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3247
3248 const string kRuntimeValue("ppp");
3249 // Setting a runtime value over the control API should overwrite both
3250 // the profile value and what we read back.
3251 Error error;
3252 manager()->mutable_store()->SetStringProperty(
3253 flimflam::kCheckPortalListProperty,
3254 kRuntimeValue,
3255 &error);
3256 ASSERT_TRUE(error.IsSuccess());
3257 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3258 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3259 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3260 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3261}
3262
Paul Stewart036dba02012-08-07 12:34:41 -07003263TEST_F(ManagerTest, LinkMonitorEnabled) {
3264 const string kEnabledTechnologies("wifi,vpn");
3265 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3266 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3267 EXPECT_FALSE(
3268 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3269}
3270
Paul Stewart85aea152013-01-22 09:31:56 -08003271TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003272 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003273 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003274 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003275 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003276 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003277 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3278 AdoptProfile(manager(), profile);
3279 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3280 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3281 scoped_ptr<MockStore> store1(new MockStore);
3282 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3283}
3284
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003285TEST_F(ManagerTest, SetEnabledStateForTechnology) {
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003286 Error error(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003287 DisableTechnologyReplyHandler disable_technology_reply_handler;
3288 ResultCallback disable_technology_callback(
3289 Bind(&DisableTechnologyReplyHandler::ReportResult,
3290 disable_technology_reply_handler.AsWeakPtr()));
3291 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_)).Times(0);
3292
3293 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3294 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003295 EXPECT_TRUE(error.IsSuccess());
3296
Joshua Krollda798622012-06-05 12:30:48 -07003297 ON_CALL(*mock_devices_[0], technology())
3298 .WillByDefault(Return(Technology::kEthernet));
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003299 ON_CALL(*mock_devices_[1], technology())
3300 .WillByDefault(Return(Technology::kCellular));
3301 ON_CALL(*mock_devices_[2], technology())
3302 .WillByDefault(Return(Technology::kCellular));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003303
3304 manager()->RegisterDevice(mock_devices_[0]);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003305 manager()->RegisterDevice(mock_devices_[1]);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003306
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003307 // Ethernet Device is disabled, so disable succeeds immediately.
Arman Uguray2f352e62013-08-28 19:12:53 -07003308 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _))
3309 .WillOnce(WithArg<1>(Invoke(SetErrorSuccess)));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003310 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003311 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3312 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003313 EXPECT_TRUE(error.IsSuccess());
3314
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003315 // Ethernet Device is enabled, and mock doesn't change error from
3316 // kOperationInitiated, so expect disable to say operation in progress.
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003317 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3318 mock_devices_[0]->enabled_ = true;
3319 error.Populate(Error::kOperationInitiated);
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003320 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, false,
3321 &error, disable_technology_callback);
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003322 EXPECT_TRUE(error.IsOngoing());
mukesh agrawal46c27cc2013-07-10 16:39:10 -07003323
3324 // Ethernet Device is disabled, and mock doesn't change error from
3325 // kOperationInitiated, so expect enable to say operation in progress.
3326 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3327 mock_devices_[0]->enabled_ = false;
3328 error.Populate(Error::kOperationInitiated);
3329 manager()->SetEnabledStateForTechnology(flimflam::kTypeEthernet, true,
3330 &error, disable_technology_callback);
3331 EXPECT_TRUE(error.IsOngoing());
3332
3333 // Cellular Device is enabled, but disable failed.
3334 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3335 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3336 mock_devices_[1]->enabled_ = true;
3337 error.Populate(Error::kOperationInitiated);
3338 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3339 &error, disable_technology_callback);
3340 EXPECT_EQ(Error::kPermissionDenied, error.type());
3341
3342 // Multiple Cellular Devices in enabled state. Should indicate IsOngoing
3343 // if one is in progress (even if the other completed immediately).
3344 manager()->RegisterDevice(mock_devices_[2]);
3345 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3346 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3347 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _));
3348 mock_devices_[1]->enabled_ = true;
3349 mock_devices_[2]->enabled_ = true;
3350 error.Populate(Error::kOperationInitiated);
3351 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3352 &error, disable_technology_callback);
3353 EXPECT_TRUE(error.IsOngoing());
3354
3355 // ...and order doesn't matter.
3356 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _));
3357 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3358 .WillOnce(WithArg<1>(Invoke(SetErrorPermissionDenied)));
3359 mock_devices_[1]->enabled_ = true;
3360 mock_devices_[2]->enabled_ = true;
3361 error.Populate(Error::kOperationInitiated);
3362 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3363 &error, disable_technology_callback);
3364 EXPECT_TRUE(error.IsOngoing());
3365 Mock::VerifyAndClearExpectations(&disable_technology_reply_handler);
3366
3367 // Multiple Cellular Devices in enabled state. Even if all disable
3368 // operations complete asynchronously, we only get one call to the
3369 // DisableTechnologyReplyHandler::ReportResult.
3370 ResultCallback device1_result_callback;
3371 ResultCallback device2_result_callback;
3372 EXPECT_CALL(*mock_devices_[1], SetEnabledPersistent(false, _, _))
3373 .WillOnce(SaveArg<2>(&device1_result_callback));
3374 EXPECT_CALL(*mock_devices_[2], SetEnabledPersistent(false, _, _))
3375 .WillOnce(DoAll(WithArg<1>(Invoke(SetErrorPermissionDenied)),
3376 SaveArg<2>(&device2_result_callback)));
3377 EXPECT_CALL(disable_technology_reply_handler, ReportResult(_));
3378 mock_devices_[1]->enabled_ = true;
3379 mock_devices_[2]->enabled_ = true;
3380 error.Populate(Error::kOperationInitiated);
3381 manager()->SetEnabledStateForTechnology(flimflam::kTypeCellular, false,
3382 &error, disable_technology_callback);
3383 EXPECT_TRUE(error.IsOngoing());
3384 device1_result_callback.Run(Error(Error::kSuccess));
3385 device2_result_callback.Run(Error(Error::kSuccess));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003386}
3387
Paul Stewart4d5efb72012-09-17 12:24:34 -07003388TEST_F(ManagerTest, IgnoredSearchList) {
3389 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003390 vector<string> ignored_paths;
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003391 SetResolver(resolver.get());
Paul Stewart4d5efb72012-09-17 12:24:34 -07003392
3393 const string kIgnored0 = "chromium.org";
3394 ignored_paths.push_back(kIgnored0);
3395 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003396 SetIgnoredDNSSearchPaths(kIgnored0, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003397 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3398
3399 const string kIgnored1 = "google.com";
3400 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3401 ignored_paths.push_back(kIgnored1);
3402 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003403 SetIgnoredDNSSearchPaths(kIgnoredSum, NULL);
Paul Stewart4d5efb72012-09-17 12:24:34 -07003404 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3405
mukesh agrawalbebf1b82013-04-23 15:06:33 -07003406 ignored_paths.clear();
3407 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3408 SetIgnoredDNSSearchPaths("", NULL);
3409 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3410
Paul Stewart4d5efb72012-09-17 12:24:34 -07003411 SetResolver(Resolver::GetInstance());
3412}
3413
Paul Stewartbfb82552012-10-24 16:48:48 -07003414TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3415 // Test to make sure that every service state-change causes the
3416 // Manager to emit a new service list.
3417 scoped_refptr<MockService> mock_service(
3418 new NiceMock<MockService>(control_interface(),
3419 dispatcher(),
3420 metrics(),
3421 manager()));
3422 EXPECT_CALL(*mock_service, state())
3423 .WillRepeatedly(Return(Service::kStateIdle));
3424
3425 manager()->RegisterService(mock_service);
3426 EXPECT_CALL(
3427 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3428 flimflam::kServicesProperty, _)).Times(1);
3429 EXPECT_CALL(
3430 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3431 flimflam::kServiceWatchListProperty, _)).Times(1);
3432 CompleteServiceSort();
3433
3434 Mock::VerifyAndClearExpectations(manager_adaptor_);
3435 EXPECT_CALL(
3436 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3437 flimflam::kServicesProperty, _)).Times(1);
3438 EXPECT_CALL(
3439 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3440 flimflam::kServiceWatchListProperty, _)).Times(1);
3441 manager()->UpdateService(mock_service.get());
3442 CompleteServiceSort();
3443
3444 manager()->DeregisterService(mock_service);
3445}
3446
3447TEST_F(ManagerTest, EnumerateServices) {
3448 scoped_refptr<MockService> mock_service(
3449 new NiceMock<MockService>(control_interface(),
3450 dispatcher(),
3451 metrics(),
3452 manager()));
3453 manager()->RegisterService(mock_service);
3454
3455 EXPECT_CALL(*mock_service, state())
3456 .WillRepeatedly(Return(Service::kStateConnected));
3457 EXPECT_CALL(*mock_service, IsVisible())
3458 .WillRepeatedly(Return(false));
3459 EXPECT_TRUE(EnumerateAvailableServices().empty());
3460 EXPECT_TRUE(EnumerateWatchedServices().empty());
3461
3462 EXPECT_CALL(*mock_service, state())
3463 .WillRepeatedly(Return(Service::kStateIdle));
3464 EXPECT_TRUE(EnumerateAvailableServices().empty());
3465 EXPECT_TRUE(EnumerateWatchedServices().empty());
3466
3467 EXPECT_CALL(*mock_service, IsVisible())
3468 .WillRepeatedly(Return(true));
3469 Service::ConnectState unwatched_states[] = {
3470 Service::kStateUnknown,
3471 Service::kStateIdle,
3472 Service::kStateFailure
3473 };
3474 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3475 EXPECT_CALL(*mock_service, state())
3476 .WillRepeatedly(Return(unwatched_states[i]));
3477 EXPECT_FALSE(EnumerateAvailableServices().empty());
3478 EXPECT_TRUE(EnumerateWatchedServices().empty());
3479 }
3480
3481 Service::ConnectState watched_states[] = {
3482 Service::kStateAssociating,
3483 Service::kStateConfiguring,
3484 Service::kStateConnected,
Paul Stewartbfb82552012-10-24 16:48:48 -07003485 Service::kStatePortal,
3486 Service::kStateOnline
3487 };
3488 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3489 EXPECT_CALL(*mock_service, state())
3490 .WillRepeatedly(Return(watched_states[i]));
3491 EXPECT_FALSE(EnumerateAvailableServices().empty());
3492 EXPECT_FALSE(EnumerateWatchedServices().empty());
3493 }
3494
3495 manager()->DeregisterService(mock_service);
3496}
3497
Paul Stewart39db5ca2013-03-18 14:15:17 -07003498TEST_F(ManagerTest, ConnectToBestServices) {
3499 scoped_refptr<MockService> wifi_service0(
3500 new NiceMock<MockService>(control_interface(),
3501 dispatcher(),
3502 metrics(),
3503 manager()));
3504 EXPECT_CALL(*wifi_service0.get(), state())
3505 .WillRepeatedly(Return(Service::kStateIdle));
3506 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3507 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003508 wifi_service0->SetConnectable(true);
3509 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003510 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3511 EXPECT_CALL(*wifi_service0.get(), technology())
3512 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003513 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3514 .WillRepeatedly(Return(false));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003515 EXPECT_CALL(*wifi_service0.get(), explicitly_disconnected())
3516 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003517
3518 scoped_refptr<MockService> wifi_service1(
3519 new NiceMock<MockService>(control_interface(),
3520 dispatcher(),
3521 metrics(),
3522 manager()));
3523 EXPECT_CALL(*wifi_service1.get(), state())
3524 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003525 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3526 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003527 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3528 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003529 wifi_service1->SetAutoConnect(true);
3530 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003531 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3532 EXPECT_CALL(*wifi_service1.get(), technology())
3533 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003534 EXPECT_CALL(*wifi_service1.get(), explicitly_disconnected())
3535 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003536
3537 scoped_refptr<MockService> wifi_service2(
3538 new NiceMock<MockService>(control_interface(),
3539 dispatcher(),
3540 metrics(),
3541 manager()));
3542 EXPECT_CALL(*wifi_service2.get(), state())
3543 .WillRepeatedly(Return(Service::kStateConnected));
3544 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3545 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003546 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3547 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003548 wifi_service2->SetAutoConnect(true);
3549 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003550 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3551 EXPECT_CALL(*wifi_service2.get(), technology())
3552 .WillRepeatedly(Return(Technology::kWifi));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003553 EXPECT_CALL(*wifi_service2.get(), explicitly_disconnected())
3554 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003555
3556 manager()->RegisterService(wifi_service0);
3557 manager()->RegisterService(wifi_service1);
3558 manager()->RegisterService(wifi_service2);
3559
3560 CompleteServiceSort();
3561 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3562
3563 scoped_refptr<MockService> cell_service(
3564 new NiceMock<MockService>(control_interface(),
3565 dispatcher(),
3566 metrics(),
3567 manager()));
3568
3569 EXPECT_CALL(*cell_service.get(), state())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003570 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003571 EXPECT_CALL(*cell_service.get(), IsConnected())
Arman Uguray6fe4f262013-08-02 20:21:55 -07003572 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003573 EXPECT_CALL(*cell_service.get(), IsVisible())
3574 .WillRepeatedly(Return(true));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003575 cell_service->SetAutoConnect(true);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003576 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003577 EXPECT_CALL(*cell_service.get(), technology())
3578 .WillRepeatedly(Return(Technology::kCellular));
Arman Uguray6fe4f262013-08-02 20:21:55 -07003579 EXPECT_CALL(*cell_service.get(), explicitly_disconnected())
3580 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003581 manager()->RegisterService(cell_service);
3582
Arman Uguray6fe4f262013-08-02 20:21:55 -07003583 scoped_refptr<MockService> wimax_service(
3584 new NiceMock<MockService>(control_interface(),
3585 dispatcher(),
3586 metrics(),
3587 manager()));
3588
3589 EXPECT_CALL(*wimax_service.get(), state())
3590 .WillRepeatedly(Return(Service::kStateConnected));
3591 EXPECT_CALL(*wimax_service.get(), IsConnected())
3592 .WillRepeatedly(Return(true));
3593 EXPECT_CALL(*wimax_service.get(), IsVisible())
3594 .WillRepeatedly(Return(true));
3595 wimax_service->SetAutoConnect(true);
3596 wimax_service->SetConnectable(true);
3597 EXPECT_CALL(*wimax_service.get(), technology())
3598 .WillRepeatedly(Return(Technology::kWiMax));
3599 EXPECT_CALL(*wimax_service.get(), explicitly_disconnected())
3600 .WillRepeatedly(Return(false));
3601 manager()->RegisterService(wimax_service);
3602
Paul Stewart39db5ca2013-03-18 14:15:17 -07003603 scoped_refptr<MockService> vpn_service(
3604 new NiceMock<MockService>(control_interface(),
3605 dispatcher(),
3606 metrics(),
3607 manager()));
3608
3609 EXPECT_CALL(*vpn_service.get(), state())
3610 .WillRepeatedly(Return(Service::kStateIdle));
3611 EXPECT_CALL(*vpn_service.get(), IsConnected())
3612 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003613 EXPECT_CALL(*vpn_service.get(), IsVisible())
3614 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003615 wifi_service2->SetAutoConnect(false);
3616 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003617 EXPECT_CALL(*vpn_service.get(), technology())
3618 .WillRepeatedly(Return(Technology::kVPN));
3619 manager()->RegisterService(vpn_service);
3620
3621 // The connected services should be at the top.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003622 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003623
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003624 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3625 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003626 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003627 EXPECT_CALL(*cell_service.get(), Connect(_, _))
3628 .Times(0); // Explicitly disconnected.
3629 EXPECT_CALL(*wimax_service.get(), Connect(_, _)).Times(0); // Is connected.
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003630 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003631
3632 manager()->ConnectToBestServices(NULL);
3633 dispatcher()->DispatchPendingEvents();
3634
3635 // After this operation, since the Connect calls above are mocked and
3636 // no actual state changes have occurred, we should expect that the
3637 // service sorting order will not have changed.
Arman Uguray6fe4f262013-08-02 20:21:55 -07003638 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wimax_service));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003639}
3640
Christopher Wiley83889862013-05-02 15:55:09 -07003641TEST_F(ManagerTest, VerifyWhenNotConnected) {
3642 const string kFakeCertificate("fake cert");
3643 const string kFakePublicKey("fake public key");
3644 const string kFakeNonce("fake public key");
3645 const string kFakeSignedData("fake signed data");
3646 const string kFakeUdn("fake udn");
3647 const vector<uint8_t> kSSID(10, 87);
3648 const string kConfiguredSSID("AConfiguredDestination");
3649 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3650 kConfiguredSSID.end());
3651 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
3652 scoped_refptr<MockWiFiService> mock_destination(
3653 new NiceMock<MockWiFiService>(control_interface(), dispatcher(),
3654 metrics(), manager(), wifi_provider_,
3655 kSSID, "", "none", false));
3656 // Register this service, but don't mark it as connected.
3657 manager()->RegisterService(mock_destination);
3658 // Verify that if we're not connected to anything, verification fails.
3659 {
3660 LOG(INFO) << "Can't verify if not connected.";
3661 EXPECT_CALL(*crypto_util_proxy_,
3662 VerifyDestination(_, _, _, _, _, _, _, _, _)).Times(0);
3663 Error error(Error::kOperationInitiated);
3664 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3665 kFakeSignedData, kFakeUdn, "", "",
3666 ResultBoolCallback(), &error);
3667 EXPECT_TRUE(error.IsFailure());
3668 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3669 }
3670 {
3671 // However, if the destination is already configured, we might be
3672 // connected to it via something other than WiFi, and we shouldn't
3673 // enforce the WiFi check.
3674 EXPECT_CALL(*crypto_util_proxy_,
3675 VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3676 kFakeSignedData, kFakeUdn,
3677 kConfiguredSSIDVector, kConfiguredBSSID,
3678 _, _)).Times(1).WillOnce(Return(true));
3679 Error error(Error::kOperationInitiated);
3680 manager()->VerifyDestination(kFakeCertificate, kFakePublicKey, kFakeNonce,
3681 kFakeSignedData, kFakeUdn, kConfiguredSSID,
3682 kConfiguredBSSID, ResultBoolCallback(),
3683 &error);
3684 EXPECT_FALSE(error.IsFailure());
3685 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3686 }
3687}
3688
Christopher Wiley1057cd72013-02-28 15:21:29 -08003689TEST_F(ManagerTest, VerifyDestination) {
3690 const string kFakeCertificate("fake cert");
3691 const string kFakePublicKey("fake public key");
3692 const string kFakeNonce("fake public key");
3693 const string kFakeSignedData("fake signed data");
3694 const string kFakeUdn("fake udn");
3695 const char kSSIDStr[] = "fake ssid";
3696 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
Christopher Wileycdde79f2013-05-01 14:26:56 -07003697 const string kConfiguredSSID("AConfiguredDestination");
3698 const vector<uint8_t> kConfiguredSSIDVector(kConfiguredSSID.begin(),
3699 kConfiguredSSID.end());
3700 const string kConfiguredBSSID("aa:bb:aa:bb:aa:bb");
Christopher Wiley1057cd72013-02-28 15:21:29 -08003701 const string kFakeData("muffin man");
3702 scoped_refptr<MockWiFiService> mock_destination(
3703 new NiceMock<MockWiFiService>(control_interface(),
3704 dispatcher(),
3705 metrics(),
3706 manager(),
3707 wifi_provider_,
3708 kSSID,
3709 "",
3710 "none",
3711 false));
3712 manager()->RegisterService(mock_destination);
Christopher Wiley1057cd72013-02-28 15:21:29 -08003713 // Making the service look online will let service lookup in
3714 // VerifyDestinatoin succeed.
3715 EXPECT_CALL(*mock_destination.get(), IsConnected())
3716 .WillRepeatedly(Return(true));
Christopher Wiley83889862013-05-02 15:55:09 -07003717 StrictMock<DestinationVerificationTest> dv_test;
Christopher Wiley1057cd72013-02-28 15:21:29 -08003718
3719 // Lead off by verifying that the basic VerifyDestination flow works.
3720 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003721 LOG(INFO) << "Basic VerifyDestination flow.";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003722 ResultBoolCallback passed_down_callback;
3723 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3724 kFakePublicKey,
3725 kFakeNonce,
3726 kFakeSignedData,
3727 kFakeUdn,
3728 kSSID,
3729 _,
3730 _,
3731 _))
3732 .Times(1)
3733 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3734 // Ask the manager to verify the current destination. This should look
3735 // up our previously registered service, and pass some metadata about
3736 // that service down to the CryptoUtilProxy to verify.
3737 Error error(Error::kOperationInitiated);
3738 ResultBoolCallback cb = Bind(
3739 &DestinationVerificationTest::ResultBoolCallbackStub,
3740 dv_test.AsWeakPtr());
3741 manager()->VerifyDestination(kFakeCertificate,
3742 kFakePublicKey,
3743 kFakeNonce,
3744 kFakeSignedData,
3745 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003746 // Ask to be verified against that service.
3747 "", "",
3748 cb,
3749 &error);
3750 // We assert here, because if the operation is not ongoing, it is
3751 // inconsistent with shim behavior to call the callback anyway.
3752 ASSERT_TRUE(error.IsOngoing());
3753 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3754 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3755 // Call the callback passed into the CryptoUtilProxy, which
3756 // should find its way into the callback passed into the manager.
3757 // In real code, that callback passed into the manager is from the
3758 // DBus adaptor.
3759 Error e;
3760 passed_down_callback.Run(e, true);
3761 Mock::VerifyAndClearExpectations(&dv_test);
3762 }
3763
Christopher Wiley1057cd72013-02-28 15:21:29 -08003764 // Now for a slightly more complex variant. When we encrypt data,
3765 // we do the same verification step but monkey with the callback to
3766 // link ourselves to an encrypt step afterward.
3767 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003768 LOG(INFO) << "Basic VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003769 ResultBoolCallback passed_down_callback;
3770 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3771 kFakePublicKey,
3772 kFakeNonce,
3773 kFakeSignedData,
3774 kFakeUdn,
3775 kSSID,
3776 _,
3777 _,
3778 _))
3779 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3780
3781 Error error(Error::kOperationInitiated);
3782 ResultStringCallback cb = Bind(
3783 &DestinationVerificationTest::ResultStringCallbackStub,
3784 dv_test.AsWeakPtr());
3785 manager()->VerifyAndEncryptData(kFakeCertificate,
3786 kFakePublicKey,
3787 kFakeNonce,
3788 kFakeSignedData,
3789 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003790 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003791 kFakeData,
3792 cb,
3793 &error);
3794 ASSERT_TRUE(error.IsOngoing());
3795 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3796 // Now, if we call that passed down callback, we should see encrypt being
3797 // called.
3798 ResultStringCallback second_passed_down_callback;
3799 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3800 kFakeData,
3801 _,
3802 _))
3803 .Times(1)
3804 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3805 Return(true)));
3806 Error e;
3807 passed_down_callback.Run(e, true);
3808 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3809 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3810 // And if we call the second passed down callback, we should see the
3811 // original function we passed down to VerifyDestination getting called.
3812 e.Reset();
3813 second_passed_down_callback.Run(e, "");
3814 Mock::VerifyAndClearExpectations(&dv_test);
3815 }
3816
3817 // If verification fails on the way to trying to encrypt, we should ditch
3818 // without calling encrypt at all.
3819 {
Christopher Wileycdde79f2013-05-01 14:26:56 -07003820 LOG(INFO) << "Failed VerifyAndEncryptData";
Christopher Wiley1057cd72013-02-28 15:21:29 -08003821 ResultBoolCallback passed_down_callback;
3822 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3823 kFakePublicKey,
3824 kFakeNonce,
3825 kFakeSignedData,
3826 kFakeUdn,
3827 kSSID,
3828 _,
3829 _,
3830 _))
3831 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3832
3833 Error error(Error::kOperationInitiated);
3834 ResultStringCallback cb = Bind(
3835 &DestinationVerificationTest::ResultStringCallbackStub,
3836 dv_test.AsWeakPtr());
3837 manager()->VerifyAndEncryptData(kFakeCertificate,
3838 kFakePublicKey,
3839 kFakeNonce,
3840 kFakeSignedData,
3841 kFakeUdn,
Christopher Wileycdde79f2013-05-01 14:26:56 -07003842 "", "",
Christopher Wiley1057cd72013-02-28 15:21:29 -08003843 kFakeData,
3844 cb,
3845 &error);
3846 ASSERT_TRUE(error.IsOngoing());
3847 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3848 Error e(Error::kOperationFailed);
3849 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3850 // Although we're ditching, this callback is what cleans up the pending
3851 // DBus call.
3852 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3853 passed_down_callback.Run(e, false);
3854 Mock::VerifyAndClearExpectations(&dv_test);
3855 }
3856}
3857
Paul Stewartd2e1c362013-03-03 19:06:07 -08003858TEST_F(ManagerTest, IsProfileBefore) {
3859 scoped_refptr<MockProfile> profile0(
3860 new NiceMock<MockProfile>(
3861 control_interface(), metrics(), manager(), ""));
3862 scoped_refptr<MockProfile> profile1(
3863 new NiceMock<MockProfile>(
3864 control_interface(), metrics(), manager(), ""));
3865
3866 AdoptProfile(manager(), profile0);
3867 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3868 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3869 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3870
3871 // A few abnormal cases, but it's good to track their behavior.
3872 scoped_refptr<MockProfile> profile2(
3873 new NiceMock<MockProfile>(
3874 control_interface(), metrics(), manager(), ""));
3875 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3876 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3877 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3878 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3879}
3880
Paul Stewart967eaeb2013-04-25 19:53:07 -07003881TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
3882 MockStore storage0;
3883 MockStore storage1;
3884 MockStore storage2;
3885
3886 scoped_refptr<MockProfile> profile0(
3887 new NiceMock<MockProfile>(
3888 control_interface(), metrics(), manager(), ""));
3889 scoped_refptr<MockProfile> profile1(
3890 new NiceMock<MockProfile>(
3891 control_interface(), metrics(), manager(), ""));
3892 scoped_refptr<MockProfile> profile2(
3893 new NiceMock<MockProfile>(
3894 control_interface(), metrics(), manager(), ""));
3895
3896 AdoptProfile(manager(), profile0);
3897 AdoptProfile(manager(), profile1);
3898 AdoptProfile(manager(), profile2);
3899
3900 scoped_refptr<MockService> service(
3901 new NiceMock<MockService>(control_interface(),
3902 dispatcher(),
3903 metrics(),
3904 manager()));
3905
3906 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
3907 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
3908 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
3909
3910 const string kEntry0("aluminum_crutch");
3911 const string kEntry2("rehashed_faces");
3912
3913 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
3914 .WillOnce(Return(kEntry0));
3915 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
3916 .WillOnce(Return(""));
3917 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
3918 .WillOnce(Return(kEntry2));
3919
3920 const string kProfileRpc0("service_station");
3921 const string kProfileRpc2("crystal_tiaras");
3922
3923 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
3924 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
3925 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
3926
3927 map<string, string> entries =
3928 manager()->GetLoadableProfileEntriesForService(service);
3929 EXPECT_EQ(2, entries.size());
3930 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
3931 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
3932 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
3933 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
3934}
3935
mukesh agrawal00752532013-05-03 15:46:55 -07003936TEST_F(ManagerTest, InitializeProfilesInformsProviders) {
mukesh agrawald142fd62013-05-01 16:50:57 -07003937 // We need a real glib here, so that profiles are persisted.
3938 GLib glib;
3939 ScopedTempDir temp_dir;
3940 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3941 Manager manager(control_interface(),
3942 dispatcher(),
3943 metrics(),
3944 &glib,
3945 run_path(),
3946 storage_path(),
3947 temp_dir.path().value());
3948 // Can't use |wifi_provider_|, because it's owned by the Manager
3949 // object in the fixture.
3950 MockWiFiProvider *wifi_provider = new NiceMock<MockWiFiProvider>();
3951 manager.wifi_provider_.reset(wifi_provider); // pass ownership
Paul Stewartb87d22b2013-07-29 11:11:37 -07003952 manager.UpdateProviderMapping();
mukesh agrawald142fd62013-05-01 16:50:57 -07003953 // Give manager a valid place to write the user profile list.
3954 manager.user_profile_list_path_ = temp_dir.path().Append("user_profile_list");
3955
3956 // With no user profiles, the WiFiProvider should be called once
3957 // (for the default profile).
3958 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_));
3959 manager.InitializeProfiles();
3960 Mock::VerifyAndClearExpectations(wifi_provider);
3961
3962 // With |n| user profiles, the WiFiProvider should be called |n+1|
3963 // times. First, create 2 user profiles...
3964 const char kProfile0[] = "~user/profile0";
3965 const char kProfile1[] = "~user/profile1";
3966 string profile_rpc_path;
3967 Error error;
3968 manager.CreateProfile(kProfile0, &profile_rpc_path, &error);
3969 manager.PushProfile(kProfile0, &profile_rpc_path, &error);
3970 manager.CreateProfile(kProfile1, &profile_rpc_path, &error);
3971 manager.PushProfile(kProfile1, &profile_rpc_path, &error);
3972
3973 // ... then reset manager state ...
3974 manager.profiles_.clear();
3975
3976 // ...then check that the WiFiProvider is notified about all three
3977 // profiles (one default, two user).
3978 EXPECT_CALL(*wifi_provider, CreateServicesFromProfile(_)).Times(3);
3979 manager.InitializeProfiles();
3980 Mock::VerifyAndClearExpectations(wifi_provider);
3981}
3982
mukesh agrawal00752532013-05-03 15:46:55 -07003983TEST_F(ManagerTest, InitializeProfilesHandlesDefaults) {
3984 // We need a real glib here, so that profiles are persisted.
3985 GLib glib;
3986 ScopedTempDir temp_dir;
3987 scoped_ptr<Manager> manager;
3988 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
3989
3990 // Instantiate a Manager with empty persistent storage. Check that
3991 // defaults are set.
3992 //
3993 // Note that we use the same directory for default and user profiles.
3994 // This doesn't affect the test results, because we don't push a
3995 // user profile.
3996 manager.reset(new Manager(control_interface(),
3997 dispatcher(),
3998 metrics(),
3999 &glib,
4000 run_path(),
4001 temp_dir.path().value(),
4002 temp_dir.path().value()));
4003 manager->InitializeProfiles();
4004 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4005 manager->props_.check_portal_list);
4006 EXPECT_EQ(Resolver::kDefaultIgnoredSearchList,
4007 manager->props_.ignored_dns_search_paths);
4008 EXPECT_EQ(LinkMonitor::kDefaultLinkMonitorTechnologies,
4009 manager->props_.link_monitor_technologies);
4010 EXPECT_EQ(PortalDetector::kDefaultURL,
4011 manager->props_.portal_url);
4012 EXPECT_EQ(PortalDetector::kDefaultCheckIntervalSeconds,
4013 manager->props_.portal_check_interval_seconds);
4014
4015 // Change one of the settings.
4016 static const string kCustomCheckPortalList = "fiber0";
4017 Error error;
4018 manager->SetCheckPortalList(kCustomCheckPortalList, &error);
4019 manager->profiles_[0]->Save();
4020
4021 // Instantiate a new manager. It should have our settings for
4022 // check_portal_list, rather than the default.
4023 manager.reset(new Manager(control_interface(),
4024 dispatcher(),
4025 metrics(),
4026 &glib,
4027 run_path(),
4028 temp_dir.path().value(),
4029 temp_dir.path().value()));
4030 manager->InitializeProfiles();
4031 EXPECT_EQ(kCustomCheckPortalList, manager->props_.check_portal_list);
4032
4033 // If we clear the persistent storage, we again get the default value.
4034 ASSERT_TRUE(temp_dir.Delete());
4035 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4036 manager.reset(new Manager(control_interface(),
4037 dispatcher(),
4038 metrics(),
4039 &glib,
4040 run_path(),
4041 temp_dir.path().value(),
4042 temp_dir.path().value()));
4043 manager->InitializeProfiles();
4044 EXPECT_EQ(PortalDetector::kDefaultCheckPortalList,
4045 manager->props_.check_portal_list);
4046}
4047
mukesh agrawalb94adde2013-08-22 18:17:26 -07004048TEST_F(ManagerTest, ProfileStackChangeLogging) {
4049 // We use a real glib here, since Manager and Profile don't provide an
4050 // easy way to mock out KeyFileStore.
4051 GLib glib;
4052 ScopedTempDir temp_dir;
4053 scoped_ptr<Manager> manager;
4054 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
4055 manager.reset(new Manager(control_interface(),
4056 dispatcher(),
4057 metrics(),
4058 &glib,
4059 run_path(),
4060 temp_dir.path().value(),
4061 temp_dir.path().value()));
4062
4063 ScopedMockLog log;
4064 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
4065 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("1 profile(s)")));
4066 manager->InitializeProfiles();
4067
4068 const char kProfile0[] = "~user/profile0";
4069 const char kProfile1[] = "~user/profile1";
4070 const char kProfile2[] = "~user/profile2";
4071 TestCreateProfile(manager.get(), kProfile0);
4072 TestCreateProfile(manager.get(), kProfile1);
4073 TestCreateProfile(manager.get(), kProfile2);
4074
4075 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("2 profile(s)")));
4076 TestPushProfile(manager.get(), kProfile0);
4077
4078 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("3 profile(s)")));
4079 TestInsertUserProfile(manager.get(), kProfile1, "not-so-random-string");
4080
4081 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("4 profile(s)")));
4082 TestInsertUserProfile(manager.get(), kProfile2, "very-random-string");
4083
4084 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("3 profile(s)")));
4085 TestPopProfile(manager.get(), kProfile2);
4086
4087 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("2 profile(s)")));
4088 TestPopAnyProfile(manager.get());
4089
4090 EXPECT_CALL(log, Log(logging::LOG_INFO, _, HasSubstr("1 profile(s)")));
4091 TestPopAllUserProfiles(manager.get());
4092}
4093
mukesh agrawalbebf1b82013-04-23 15:06:33 -07004094// Custom property setters should return false, and make no changes, if
4095// the new value is the same as the old value.
4096TEST_F(ManagerTest, CustomSetterNoopChange) {
4097 // SetCheckPortalList
4098 {
4099 static const string kCheckPortalList = "weird-device,weirder-device";
4100 Error error;
4101 // Set to known value.
4102 EXPECT_TRUE(SetCheckPortalList(kCheckPortalList, &error));
4103 EXPECT_TRUE(error.IsSuccess());
4104 // Set to same value.
4105 EXPECT_FALSE(SetCheckPortalList(kCheckPortalList, &error));
4106 EXPECT_TRUE(error.IsSuccess());
4107 }
4108
4109 // SetIgnoredDNSSearchPaths
4110 {
4111 NiceMock<MockResolver> resolver;
4112 static const string kIgnoredPaths = "example.com,example.org";
4113 Error error;
4114 SetResolver(&resolver);
4115 // Set to known value.
4116 EXPECT_CALL(resolver, set_ignored_search_list(_));
4117 EXPECT_TRUE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4118 EXPECT_TRUE(error.IsSuccess());
4119 Mock::VerifyAndClearExpectations(&resolver);
4120 // Set to same value.
4121 EXPECT_CALL(resolver, set_ignored_search_list(_)).Times(0);
4122 EXPECT_FALSE(SetIgnoredDNSSearchPaths(kIgnoredPaths, &error));
4123 EXPECT_TRUE(error.IsSuccess());
4124 Mock::VerifyAndClearExpectations(&resolver);
4125 }
4126}
4127
Paul Stewart7de7e022013-08-28 09:42:50 -07004128TEST_F(ManagerTest, GeoLocation) {
4129 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4130
4131 auto device = make_scoped_refptr(new NiceMock<MockDevice>(control_interface(),
4132 dispatcher(),
4133 metrics(),
4134 manager(),
4135 "null",
4136 "addr",
4137 0));
4138
4139 // Manager should ignore gelocation info from technologies it does not know.
4140 EXPECT_CALL(*device, technology())
4141 .Times(AtLeast(1))
4142 .WillRepeatedly(Return(Technology::kEthernet));
4143 EXPECT_CALL(*device, GetGeolocationObjects()).Times(0);
4144 manager()->OnDeviceGeolocationInfoUpdated(device);
4145 Mock::VerifyAndClearExpectations(device);
4146 EXPECT_TRUE(manager()->GetNetworksForGeolocation().empty());
4147
4148 // Manager should add WiFi geolocation info.
4149 EXPECT_CALL(*device, technology())
4150 .Times(AtLeast(1))
4151 .WillRepeatedly(Return(Technology::kWifi));
4152 EXPECT_CALL(*device, GetGeolocationObjects())
4153 .WillOnce(Return(vector<GeolocationInfo>()));
4154 manager()->OnDeviceGeolocationInfoUpdated(device);
4155 Mock::VerifyAndClearExpectations(device);
4156 auto location_infos = manager()->GetNetworksForGeolocation();
4157 EXPECT_EQ(1, location_infos.size());
4158 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4159
4160 // Manager should inclusively add cellular info.
4161 EXPECT_CALL(*device, technology())
4162 .Times(AtLeast(1))
4163 .WillRepeatedly(Return(Technology::kCellular));
4164 EXPECT_CALL(*device, GetGeolocationObjects())
4165 .WillOnce(Return(vector<GeolocationInfo>()));
4166 manager()->OnDeviceGeolocationInfoUpdated(device);
4167 location_infos = manager()->GetNetworksForGeolocation();
4168 EXPECT_EQ(2, location_infos.size());
4169 EXPECT_TRUE(ContainsKey(location_infos, kGeoWifiAccessPointsProperty));
4170 EXPECT_TRUE(ContainsKey(location_infos, kGeoCellTowersProperty));
4171}
4172
Chris Masone9be4a9d2011-05-16 15:44:09 -07004173} // namespace shill