blob: fa752f977556526845bcf96149906faf276722c0 [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07004
5#include "shill/manager.h"
6
Jason Glasgowdf7c5532012-05-14 14:41:45 -04007#include <map>
Chris Masone6791a432011-07-12 13:23:19 -07008#include <set>
9
Chris Masone9be4a9d2011-05-16 15:44:09 -070010#include <glib.h>
11
Paul Stewarte73d05c2012-03-29 16:26:05 -070012#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080013#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070015#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070017#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070018#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070019
mukesh agrawal32399322011-09-01 10:53:43 -070020#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070021#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070022#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070023#include "shill/glib.h"
24#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070025#include "shill/key_value_store.h"
Christopher Wiley3e7635e2012-08-15 09:46:17 -070026#include "shill/logging.h"
mukesh agrawal32399322011-09-01 10:53:43 -070027#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080028#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070029#include "shill/mock_control.h"
Christopher Wiley1057cd72013-02-28 15:21:29 -080030#include "shill/mock_crypto_util_proxy.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070031#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080032#include "shill/mock_device_info.h"
Paul Stewart35eff132013-04-12 12:08:40 -070033#include "shill/mock_ethernet_eap_provider.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070034#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000035#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020036#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070037#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070038#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070039#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070040#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080041#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070042#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070043#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020044#include "shill/proxy_factory.h"
Chris Masone6515aab2011-10-12 16:19:09 -070045#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070046#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020047#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070048
Christopher Wiley1057cd72013-02-28 15:21:29 -080049using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080050using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080051using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070052using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070053using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070054using std::string;
55using std::vector;
56
Chris Masone9be4a9d2011-05-16 15:44:09 -070057namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070058using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070059using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080060using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070061using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070062using ::testing::InSequence;
mukesh agrawal784566d2012-08-08 18:32:58 -070063using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070064using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070065using ::testing::NiceMock;
Paul Stewart967eaeb2013-04-25 19:53:07 -070066using ::testing::Ref;
Chris Masone9be4a9d2011-05-16 15:44:09 -070067using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070068using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070069using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080070using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080071using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080072using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070073using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070074
Chris Masone3bd3c8c2011-06-13 08:20:26 -070075class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070076 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070077 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020078 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080079 device_info_(new NiceMock<MockDeviceInfo>(
80 control_interface(),
81 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080082 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080083 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080084 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Paul Stewart35eff132013-04-12 12:08:40 -070085 ethernet_eap_provider_(new NiceMock<MockEthernetEapProvider>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080086 wifi_provider_(new NiceMock<MockWiFiProvider>()),
87 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
88 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070089 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
90 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080091 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070092 manager(),
93 "null0",
94 "addr0",
95 0));
96 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
97 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080098 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070099 manager(),
100 "null1",
101 "addr1",
102 1));
103 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
104 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800105 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700106 manager(),
107 "null2",
108 "addr2",
109 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800110 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
111 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800112 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800113 manager(),
114 "null3",
115 "addr3",
116 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700117 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800118 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800119
120 // Replace the manager's adaptor with a quieter one, and one
121 // we can do EXPECT*() against. Passes ownership.
122 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800123
Paul Stewart35eff132013-04-12 12:08:40 -0700124 // Replace the manager's Ethernet EAP provider with our mock.
125 // Passes ownership.
126 manager()->ethernet_eap_provider_.reset(ethernet_eap_provider_);
127
Paul Stewart3c504012013-01-17 17:49:58 -0800128 // Replace the manager's WiFi provider with our mock. Passes
129 // ownership.
130 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800131
132 // Replace the manager's crypto util proxy with our mock. Passes
133 // ownership.
134 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Paul Stewart9dd253e2013-04-22 08:32:59 -0700135
136 // Reset service serial number so service sorting by unique_name()
137 // (and by extension, sorting by order of creation) is predictable.
138 Service::serial_number_ = 10000;
Chris Masone3c3f6a12011-07-01 10:01:41 -0700139 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700140 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700141
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100142 void SetMetrics(Metrics *metrics) {
143 manager()->set_metrics(metrics);
144 }
145
Paul Stewartfdd16072011-09-16 12:41:35 -0700146 bool IsDeviceRegistered(const DeviceRefPtr &device,
147 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700148 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700149 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700150 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700151 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700152 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700153
Paul Stewarta849a3d2011-11-03 05:54:09 -0700154 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
155 manager->profiles_.push_back(profile);
156 }
157
Paul Stewart63864b62012-11-07 15:10:55 -0800158 void SetRunning(bool running) {
159 manager()->running_ = running;
160 }
161
Paul Stewart75225512012-01-26 22:51:33 -0800162 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
163 return manager->ephemeral_profile_;
164 }
165
Paul Stewart307c2502013-03-23 12:32:10 -0700166 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
167 return manager->profiles_;
168 }
169
Chris Masone6515aab2011-10-12 16:19:09 -0700170 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
171 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700172 FilePath final_path(storage_path());
173 final_path = final_path.Append("test.profile");
174 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
175 storage->set_path(final_path);
176 if (!storage->Open())
177 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800178 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800179 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800180 manager,
181 id,
182 "",
183 false));
184 profile->set_storage(storage.release()); // Passes ownership of "storage".
185 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700186 }
187
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700188 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
189 const string &profile_identifier,
190 const string &service_name) {
191 GLib glib;
192 KeyFileStore store(&glib);
193 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
194 return store.Open() &&
195 store.SetString(service_name, "rather", "irrelevant") &&
196 store.Close();
197 }
198
199 Error::Type TestCreateProfile(Manager *manager, const string &name) {
200 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800201 string path;
202 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700203 return error.type();
204 }
205
206 Error::Type TestPopAnyProfile(Manager *manager) {
207 Error error;
208 manager->PopAnyProfile(&error);
209 return error.type();
210 }
211
Paul Stewart307c2502013-03-23 12:32:10 -0700212 Error::Type TestPopAllUserProfiles(Manager *manager) {
213 Error error;
214 manager->PopAllUserProfiles(&error);
215 return error.type();
216 }
217
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700218 Error::Type TestPopProfile(Manager *manager, const string &name) {
219 Error error;
220 manager->PopProfile(name, &error);
221 return error.type();
222 }
223
224 Error::Type TestPushProfile(Manager *manager, const string &name) {
225 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800226 string path;
227 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700228 return error.type();
229 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000230
Paul Stewartf3eced92013-04-17 12:18:22 -0700231 Error::Type TestInsertUserProfile(Manager *manager,
232 const string &name,
233 const string &user_hash) {
234 Error error;
235 string path;
236 manager->InsertUserProfile(name, user_hash, &path, &error);
237 return error.type();
238 }
239
Paul Stewartd2e1c362013-03-03 19:06:07 -0800240 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
241 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700242 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800243 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800244 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200245 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700246 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800247 return profile;
248 }
249
250 void AddMockProfileToManager(Manager *manager) {
251 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700252 }
253
Paul Stewartdfa46052012-06-26 09:44:14 -0700254 void CompleteServiceSort() {
255 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
256 dispatcher()->DispatchPendingEvents();
257 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
258 }
259
Paul Stewart49739c02012-08-08 17:24:03 -0700260 RpcIdentifier GetDefaultServiceRpcIdentifier() {
261 return manager()->GetDefaultServiceRpcIdentifier(NULL);
262 }
263
Paul Stewart4d5efb72012-09-17 12:24:34 -0700264 void SetResolver(Resolver *resolver) {
265 manager()->resolver_ = resolver;
266 }
267
268 void SetIgnoredDNSSearchPaths(const string &search_paths) {
269 manager()->SetIgnoredDNSSearchPaths(search_paths, NULL);
270 }
271
272 const string &GetIgnoredDNSSearchPaths() {
273 return manager()->props_.ignored_dns_search_paths;
274 }
275
Paul Stewartd2e1c362013-03-03 19:06:07 -0800276 WiFiServiceRefPtr ReleaseTempMockService() {
277 // Take a reference to hold during this function.
278 WiFiServiceRefPtr temp_service = temp_mock_service_;
279 temp_mock_service_ = NULL;
280 return temp_service;
281 }
282
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700283 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000284 typedef scoped_refptr<MockService> MockServiceRefPtr;
285
Darin Petkova5e07ef2012-07-09 14:27:57 +0200286 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
287 public:
288 ServiceWatcher() {}
289 virtual ~ServiceWatcher() {}
290
291 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
292
293 private:
294 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
295 };
296
Darin Petkovca621542012-07-25 14:25:56 +0200297 class TestProxyFactory : public ProxyFactory {
298 public:
299 TestProxyFactory() {}
300
301 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
302 PowerManagerProxyDelegate */*delegate*/) {
303 return NULL;
304 }
305
306 private:
307 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
308 };
309
Darin Petkov3ec55342012-09-28 14:04:44 +0200310 class TerminationActionTest :
311 public base::SupportsWeakPtr<TerminationActionTest> {
312 public:
313 static const char kActionName[];
314
315 TerminationActionTest() : manager_(NULL) {}
316 virtual ~TerminationActionTest() {}
317
318 MOCK_METHOD1(Done, void(const Error &error));
319
320 void Action() {
321 manager_->TerminationActionComplete("action");
322 }
323
324 void set_manager(Manager *manager) { manager_ = manager; }
325
326 private:
327 Manager *manager_;
328 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
329 };
330
Christopher Wiley1057cd72013-02-28 15:21:29 -0800331 class DestinationVerificationTest :
332 public base::SupportsWeakPtr<DestinationVerificationTest> {
333 public:
334 DestinationVerificationTest() {}
335 virtual ~DestinationVerificationTest() {}
336
337 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
338 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
339 const string &value));
340 private:
341 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
342 };
343
Darin Petkovca621542012-07-25 14:25:56 +0200344 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
345 power_manager_->power_state_ = state;
346 }
347
348 void SetPowerManager() {
349 manager()->set_power_manager(power_manager_.release());
350 }
351
Darin Petkov3ec55342012-09-28 14:04:44 +0200352 HookTable *GetTerminationActions() {
353 return &manager()->termination_actions_;
354 }
355
Darin Petkovca621542012-07-25 14:25:56 +0200356 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
357 manager()->OnPowerStateChanged(state);
358 }
359
Daniel Erat0818cca2012-12-14 10:16:21 -0800360 void OnSuspendImminent(int suspend_id) {
361 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200362 }
363
Daniel Erat0818cca2012-12-14 10:16:21 -0800364 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
365 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200366 }
367
Paul Stewartbfb82552012-10-24 16:48:48 -0700368 vector<string> EnumerateAvailableServices() {
369 return manager()->EnumerateAvailableServices(NULL);
370 }
371
372 vector<string> EnumerateWatchedServices() {
373 return manager()->EnumerateWatchedServices(NULL);
374 }
375
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000376 MockServiceRefPtr MakeAutoConnectableService() {
377 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
378 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000380 manager());
381 service->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700382 service->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000383 return service;
384 }
385
Paul Stewart35eff132013-04-12 12:08:40 -0700386 void SetEapProviderService(const ServiceRefPtr &service) {
387 ethernet_eap_provider_->set_service(service);
388 }
389
Darin Petkovca621542012-07-25 14:25:56 +0200390 TestProxyFactory proxy_factory_;
391 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700392 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800393 scoped_ptr<MockDeviceInfo> device_info_;
394
Paul Stewartd2e1c362013-03-03 19:06:07 -0800395 // This service is held for the manager, and given ownership in a mock
396 // function. This ensures that when the Manager takes ownership, there
397 // is only one reference left.
398 scoped_refptr<MockWiFiService> temp_mock_service_;
399
Paul Stewart3c504012013-01-17 17:49:58 -0800400 // These pointers are owned by the manager, and only tracked here for
401 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800402 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart35eff132013-04-12 12:08:40 -0700403 MockEthernetEapProvider *ethernet_eap_provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800404 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800405 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700406};
407
Darin Petkov3ec55342012-09-28 14:04:44 +0200408const char ManagerTest::TerminationActionTest::kActionName[] = "action";
409
Paul Stewart22aa71b2011-09-16 12:15:11 -0700410bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700411 if (!manager()->sort_services_task_.IsCancelled()) {
412 manager()->SortServicesTask();
413 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700414 return (svc0.get() == manager()->services_[0].get() &&
415 svc1.get() == manager()->services_[1].get());
416}
417
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700418TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700419 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
420 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700421}
422
Chris Masone9be4a9d2011-05-16 15:44:09 -0700423TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700424 ON_CALL(*mock_devices_[0].get(), technology())
425 .WillByDefault(Return(Technology::kEthernet));
426 ON_CALL(*mock_devices_[1].get(), technology())
427 .WillByDefault(Return(Technology::kWifi));
428 ON_CALL(*mock_devices_[2].get(), technology())
429 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700430
Paul Stewart22aa71b2011-09-16 12:15:11 -0700431 manager()->RegisterDevice(mock_devices_[0]);
432 manager()->RegisterDevice(mock_devices_[1]);
433 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700434
Paul Stewart22aa71b2011-09-16 12:15:11 -0700435 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
436 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
437 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700438}
439
Paul Stewarta41e38d2011-11-11 07:47:29 -0800440TEST_F(ManagerTest, DeviceRegistrationAndStart) {
441 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500442 mock_devices_[0]->enabled_persistent_ = true;
443 mock_devices_[1]->enabled_persistent_ = false;
444 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800445 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500446 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800447 .Times(0);
448 manager()->RegisterDevice(mock_devices_[0]);
449 manager()->RegisterDevice(mock_devices_[1]);
450}
451
452TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800453 MockProfile *profile =
454 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800455 DeviceRefPtr device_ref(mock_devices_[0].get());
456 AdoptProfile(manager(), profile); // Passes ownership.
457 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200458 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800459 manager()->RegisterDevice(mock_devices_[0]);
460}
461
Chris Masone9be4a9d2011-05-16 15:44:09 -0700462TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700463 ON_CALL(*mock_devices_[0].get(), technology())
464 .WillByDefault(Return(Technology::kEthernet));
465 ON_CALL(*mock_devices_[1].get(), technology())
466 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700467
Gaurav Shah435de2c2011-11-17 19:01:07 -0800468 manager()->RegisterDevice(mock_devices_[0]);
469 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700470
Paul Stewart22aa71b2011-09-16 12:15:11 -0700471 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
472 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700473
Thieu Le5133b712013-02-19 14:47:21 -0800474 MockProfile *profile =
475 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700476 AdoptProfile(manager(), profile); // Passes ownership.
477
Eric Shienbrood9a245532012-03-07 14:20:39 -0500478 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700479 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800480 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700481 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700482
Eric Shienbrood9a245532012-03-07 14:20:39 -0500483 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700484 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800485 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700486 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700487}
488
489TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700490 // It's much easier and safer to use a real GLib for this test.
491 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700492 Manager manager(control_interface(),
493 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800494 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700495 &glib,
496 run_path(),
497 storage_path(),
498 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700499 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
500 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700501 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700502
Chris Masone9be4a9d2011-05-16 15:44:09 -0700503 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700504 new NiceMock<MockService>(control_interface(),
505 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800506 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700507 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700508 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700509 new NiceMock<MockService>(control_interface(),
510 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800511 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700512 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700513
Darin Petkov457728b2013-01-09 09:49:08 +0100514 string service1_name(mock_service->unique_name());
515 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700516
517 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
518 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700519 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700520 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700521 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700522 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700523 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700524
Chris Masone9d779932011-08-25 16:33:41 -0700525 manager.RegisterService(mock_service);
526 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700527
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800528 Error error;
529 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700530 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700531 EXPECT_EQ(2, ids.size());
532 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
533 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700534
Chris Masone9d779932011-08-25 16:33:41 -0700535 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
536 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
537
538 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700539}
540
Chris Masone6515aab2011-10-12 16:19:09 -0700541TEST_F(ManagerTest, RegisterKnownService) {
542 // It's much easier and safer to use a real GLib for this test.
543 GLib glib;
544 Manager manager(control_interface(),
545 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800546 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700547 &glib,
548 run_path(),
549 storage_path(),
550 string());
551 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
552 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700553 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700554 {
555 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
556 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800557 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700558 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700559 ASSERT_TRUE(profile->AdoptService(service1));
560 ASSERT_TRUE(profile->ContainsService(service1));
561 } // Force destruction of service1.
562
563 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
564 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800565 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700566 &manager));
567 manager.RegisterService(service2);
568 EXPECT_EQ(service2->profile().get(), profile.get());
569 manager.Stop();
570}
571
572TEST_F(ManagerTest, RegisterUnknownService) {
573 // It's much easier and safer to use a real GLib for this test.
574 GLib glib;
575 Manager manager(control_interface(),
576 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800577 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700578 &glib,
579 run_path(),
580 storage_path(),
581 string());
582 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
583 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700584 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700585 {
586 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
587 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800588 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700589 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700590 ASSERT_TRUE(profile->AdoptService(service1));
591 ASSERT_TRUE(profile->ContainsService(service1));
592 } // Force destruction of service1.
593 scoped_refptr<MockService> mock_service2(
594 new NiceMock<MockService>(control_interface(),
595 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800596 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700597 &manager));
598 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100599 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700600 manager.RegisterService(mock_service2);
601 EXPECT_NE(mock_service2->profile().get(), profile.get());
602 manager.Stop();
603}
604
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000605TEST_F(ManagerTest, DeregisterUnregisteredService) {
606 // WiFi assumes that it can deregister a service that is not
607 // registered. (E.g. a hidden service can be deregistered when it
608 // loses its last endpoint, and again when WiFi is Stop()-ed.)
609 //
610 // So test that doing so doesn't cause a crash.
611 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
612 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800613 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000614 manager());
615 manager()->DeregisterService(service);
616}
617
Chris Masonea8a2c252011-06-27 22:16:30 -0700618TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700619 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700620 map<string, ::DBus::Variant> props;
621 Error error(Error::kInvalidProperty, "");
622 {
623 ::DBus::Error dbus_error;
624 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700625 manager()->mutable_store()->SetStringProperty(
626 flimflam::kCheckPortalListProperty,
627 expected,
628 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700629 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700630 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
631 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
632 expected);
633 }
634 {
635 ::DBus::Error dbus_error;
636 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700637 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
638 expected,
639 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700640 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700641 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
642 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
643 expected);
644 }
645}
646
Chris Masone3c3f6a12011-07-01 10:01:41 -0700647TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700648 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800649 manager()->RegisterDevice(mock_devices_[0]);
650 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700651 {
652 map<string, ::DBus::Variant> props;
653 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700654 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700655 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700656 vector < ::DBus::Path> devices =
657 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700658 EXPECT_EQ(2, devices.size());
659 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700660}
661
mukesh agrawal2366eed2012-03-20 18:21:50 -0700662TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700663 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700664 map<string, ::DBus::Variant> props;
665 ::DBus::Error dbus_error;
666 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
667 map<string, ::DBus::Variant>::const_iterator prop =
668 props.find(flimflam::kServicesProperty);
669 ASSERT_FALSE(prop == props.end());
670 const ::DBus::Variant &variant = prop->second;
671 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
672}
673
Chris Masone6791a432011-07-12 13:23:19 -0700674TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700675 Manager manager(control_interface(),
676 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800677 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700678 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700679 run_path(),
680 storage_path(),
681 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700682 scoped_refptr<MockService> s2(new MockService(control_interface(),
683 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800684 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700685 &manager));
686 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700687 {
Chris Masone6515aab2011-10-12 16:19:09 -0700688 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700689 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800690 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700691 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700692 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700693 .WillRepeatedly(Return(true));
694 EXPECT_CALL(*storage, Flush())
695 .Times(AnyNumber())
696 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700697 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700698 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700699 }
Chris Masone6515aab2011-10-12 16:19:09 -0700700 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800701 ProfileRefPtr profile(
702 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700703 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700704
Chris Masone6515aab2011-10-12 16:19:09 -0700705 // Now, move the Service |s2| to another profile.
706 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
707 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700708
709 // Force destruction of the original Profile, to ensure that the Service
710 // is kept alive and populated with data.
711 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700712 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700713 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700714}
715
Paul Stewart7f61e522012-03-22 11:13:45 -0700716TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
717 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800718 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700719 const string kProfileName("profile0");
720 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
721 .WillRepeatedly(Return(kProfileName));
722 AdoptProfile(manager(), mock_profile);
723
724 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
725 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
726 EXPECT_EQ(mock_profile.get(), profile.get());
727}
728
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800729TEST_F(ManagerTest, SetProfileForService) {
730 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800731 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800732 string profile_name0("profile0");
733 EXPECT_CALL(*profile0, GetRpcIdentifier())
734 .WillRepeatedly(Return(profile_name0));
735 AdoptProfile(manager(), profile0);
736 scoped_refptr<MockService> service(new MockService(control_interface(),
737 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800738 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800739 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700740 EXPECT_FALSE(manager()->HasService(service));
741 {
742 Error error;
743 EXPECT_CALL(*profile0, AdoptService(_))
744 .WillOnce(Return(true));
745 // Expect that setting the profile of a service that does not already
746 // have one assigned does not cause a crash.
747 manager()->SetProfileForService(service, "profile0", &error);
748 EXPECT_TRUE(error.IsSuccess());
749 }
750
751 // The service should be registered as a side-effect of the profile being
752 // set for this service.
753 EXPECT_TRUE(manager()->HasService(service));
754
755 // Since we have mocked Profile::AdoptServie() above, the service's
756 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800757 service->set_profile(profile0);
758
759 {
760 Error error;
761 manager()->SetProfileForService(service, "foo", &error);
762 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700763 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800764 }
765
766 {
767 Error error;
768 manager()->SetProfileForService(service, profile_name0, &error);
769 EXPECT_EQ(Error::kInvalidArguments, error.type());
770 EXPECT_EQ("Service is already connected to this profile", error.message());
771 }
772
773 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800774 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800775 string profile_name1("profile1");
776 EXPECT_CALL(*profile1, GetRpcIdentifier())
777 .WillRepeatedly(Return(profile_name1));
778 AdoptProfile(manager(), profile1);
779
780 {
781 Error error;
782 EXPECT_CALL(*profile1, AdoptService(_))
783 .WillOnce(Return(true));
784 EXPECT_CALL(*profile0, AbandonService(_))
785 .WillOnce(Return(true));
786 manager()->SetProfileForService(service, profile_name1, &error);
787 EXPECT_TRUE(error.IsSuccess());
788 }
789}
790
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700791TEST_F(ManagerTest, CreateProfile) {
792 // It's much easier to use real Glib here since we want the storage
793 // side-effects.
794 GLib glib;
795 ScopedTempDir temp_dir;
796 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
797
798 Manager manager(control_interface(),
799 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800800 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700801 &glib,
802 run_path(),
803 storage_path(),
804 temp_dir.path().value());
805
806 // Invalid name should be rejected.
807 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
808
Paul Stewartd0a3b812012-03-28 22:48:22 -0700809 // A profile with invalid characters in it should similarly be rejected.
810 EXPECT_EQ(Error::kInvalidArguments,
811 TestCreateProfile(&manager, "valid_profile"));
812
813 // We should be able to create a machine profile.
814 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700815
Gary Morainb672d352012-04-25 09:19:06 -0700816 // We should succeed in creating a valid user profile. Verify the returned
817 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700818 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700819 {
820 Error error;
821 string path;
822 manager.CreateProfile(kProfile, &path, &error);
823 EXPECT_EQ(Error::kSuccess, error.type());
824 EXPECT_EQ("/profile_rpc", path);
825 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700826
827 // We should fail in creating it a second time (already exists).
828 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
829}
830
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700831// We receive PopProfile when a user logs out, and it should always trigger a
832// MemoryLog Clear() call.
833TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
834 GLib glib;
835 ScopedTempDir temp_dir;
836 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
837 Manager manager(control_interface(),
838 dispatcher(),
839 metrics(),
840 &glib,
841 run_path(),
842 storage_path(),
843 temp_dir.path().value());
844 const char kProfile0[] = "~user/profile0";
845 const char kPurgedMessage[] = "This message should be purged";
846 // Create a profile and push it on the stack, leave one uncreated
847 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
848 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
849
850 // Popping a profile which isn't on top should still clear the log.
851 LOG(INFO) << kPurgedMessage;
852 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
853 kPurgedMessage));
854 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
855 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
856 kPurgedMessage));
857
858 // Popping an invalid profile name should do the same thing.
859 LOG(INFO) << kPurgedMessage;
860 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
861 kPurgedMessage));
862 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
863 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
864 kPurgedMessage));
865
866 // Successful pops also purge the message log.
867 LOG(INFO) << kPurgedMessage;
868 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
869 kPurgedMessage));
870 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
871 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
872 kPurgedMessage));
873}
874
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700875TEST_F(ManagerTest, PushPopProfile) {
876 // It's much easier to use real Glib in creating a Manager for this
877 // test here since we want the storage side-effects.
878 GLib glib;
879 ScopedTempDir temp_dir;
880 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
881 Manager manager(control_interface(),
882 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800883 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700884 &glib,
885 run_path(),
886 storage_path(),
887 temp_dir.path().value());
888
889 // Pushing an invalid profile should fail.
890 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
891
Paul Stewartd0a3b812012-03-28 22:48:22 -0700892 // Pushing a default profile that does not exist should fail.
893 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700894
895 const char kProfile0[] = "~user/profile0";
896 const char kProfile1[] = "~user/profile1";
897
898 // Create a couple of profiles.
899 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
900 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
901
902 // Push these profiles on the stack.
903 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
904 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
905
906 // Pushing a profile a second time should fail.
907 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
908 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
909
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800910 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700911 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800912 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700913
914 // Make sure a profile name that doesn't exist fails.
915 const char kProfile2Id[] = "profile2";
916 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
917 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
918
919 // Create a new service, with a specific storage name.
920 scoped_refptr<MockService> service(
921 new NiceMock<MockService>(control_interface(),
922 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800923 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700924 &manager));
925 const char kServiceName[] = "service_storage_name";
926 EXPECT_CALL(*service.get(), GetStorageIdentifier())
927 .WillRepeatedly(Return(kServiceName));
928 EXPECT_CALL(*service.get(), Load(_))
929 .WillRepeatedly(Return(true));
930
931 // Add this service to the manager -- it should end up in the ephemeral
932 // profile.
933 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800934 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700935
936 // Create storage for a profile that contains the service storage name.
937 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
938 kServiceName));
939
940 // When we push the profile, the service should move away from the
941 // ephemeral profile to this new profile since it has an entry for
942 // this service.
943 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800944 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700945 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
946
947 // Insert another profile that should supersede ownership of the service.
948 const char kProfile3Id[] = "profile3";
949 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
950 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
951 kServiceName));
952 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
953 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
954
955 // Popping an invalid profile name should fail.
956 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
957
958 // Popping an profile that is not at the top of the stack should fail.
959 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
960
961 // Popping the top profile should succeed.
962 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
963
964 // Moreover the service should have switched profiles to profile 2.
965 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
966
967 // Popping the top profile should succeed.
968 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
969
970 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800971 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700972
973 // Pop the remaining two services off the stack.
974 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
975 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
976
977 // Next pop should fail with "stack is empty".
978 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700979
980 const char kMachineProfile0[] = "machineprofile0";
981 const char kMachineProfile1[] = "machineprofile1";
982 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
983 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
984
985 // Should be able to push a machine profile.
986 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
987
988 // Should be able to push a user profile atop a machine profile.
989 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
990
991 // Pushing a system-wide profile on top of a user profile should fail.
992 EXPECT_EQ(Error::kInvalidArguments,
993 TestPushProfile(&manager, kMachineProfile1));
994
995 // However if we pop the user profile, we should be able stack another
996 // machine profile on.
997 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
998 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -0700999
1000 // Add two user profiles to the top of the stack.
1001 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1002 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
1003 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
1004 EXPECT_EQ(4, profiles.size());
1005
1006 // PopAllUserProfiles should remove both user profiles, leaving the two
1007 // machine profiles.
1008 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
1009 EXPECT_EQ(2, profiles.size());
1010 EXPECT_TRUE(profiles[0]->GetUser().empty());
1011 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -07001012
1013 // Use InsertUserProfile() instead. Although a machine profile is valid
1014 // in this state, it cannot be added via InsertUserProfile.
1015 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1016 EXPECT_EQ(Error::kInvalidArguments,
1017 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1018 const char kUserHash0[] = "userhash0";
1019 const char kUserHash1[] = "userhash1";
1020 EXPECT_EQ(Error::kSuccess,
1021 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1022 EXPECT_EQ(Error::kSuccess,
1023 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1024 EXPECT_EQ(3, profiles.size());
1025 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1026 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001027}
1028
Paul Stewarte73d05c2012-03-29 16:26:05 -07001029TEST_F(ManagerTest, RemoveProfile) {
1030 // It's much easier to use real Glib in creating a Manager for this
1031 // test here since we want the storage side-effects.
1032 GLib glib;
1033 ScopedTempDir temp_dir;
1034 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1035 Manager manager(control_interface(),
1036 dispatcher(),
1037 metrics(),
1038 &glib,
1039 run_path(),
1040 storage_path(),
1041 temp_dir.path().value());
1042
1043 const char kProfile0[] = "profile0";
1044 FilePath profile_path(
1045 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1046
1047 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1048 ASSERT_TRUE(file_util::PathExists(profile_path));
1049
1050 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1051
1052 // Remove should fail since the profile is still on the stack.
1053 {
1054 Error error;
1055 manager.RemoveProfile(kProfile0, &error);
1056 EXPECT_EQ(Error::kInvalidArguments, error.type());
1057 }
1058
1059 // Profile path should still exist.
1060 EXPECT_TRUE(file_util::PathExists(profile_path));
1061
1062 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1063
1064 // This should succeed now that the profile is off the stack.
1065 {
1066 Error error;
1067 manager.RemoveProfile(kProfile0, &error);
1068 EXPECT_EQ(Error::kSuccess, error.type());
1069 }
1070
1071 // Profile path should no longer exist.
1072 EXPECT_FALSE(file_util::PathExists(profile_path));
1073
1074 // Another remove succeeds, due to a foible in file_util::Delete --
1075 // it is not an error to delete a file that does not exist.
1076 {
1077 Error error;
1078 manager.RemoveProfile(kProfile0, &error);
1079 EXPECT_EQ(Error::kSuccess, error.type());
1080 }
1081
1082 // Let's create an error case that will "work". Create a non-empty
1083 // directory in the place of the profile pathname.
1084 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1085 {
1086 Error error;
1087 manager.RemoveProfile(kProfile0, &error);
1088 EXPECT_EQ(Error::kOperationFailed, error.type());
1089 }
1090}
1091
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001092TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1093 // It's much easier to use real Glib in creating a Manager for this
1094 // test here since we want the storage side-effects.
1095 GLib glib;
1096 ScopedTempDir temp_dir;
1097 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1098 Manager manager(control_interface(),
1099 dispatcher(),
1100 metrics(),
1101 &glib,
1102 run_path(),
1103 storage_path(),
1104 temp_dir.path().value());
1105
1106 const char kProfile0[] = "profile0";
1107 FilePath profile_path(
1108 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1109
1110 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1111 ASSERT_TRUE(file_util::PathExists(profile_path));
1112 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1113
1114 // Ensure that even if the backing filestore is removed, we still can't
1115 // create a profile twice.
1116 ASSERT_TRUE(file_util::Delete(profile_path, false));
1117 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1118}
1119
Paul Stewart75225512012-01-26 22:51:33 -08001120// Use this matcher instead of passing RefPtrs directly into the arguments
1121// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1122// system teardown.
1123MATCHER_P(IsRefPtrTo, ref_address, "") {
1124 return arg.get() == ref_address;
1125}
1126
1127TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1128 MockServiceRefPtr s_not_in_profile(
1129 new NiceMock<MockService>(control_interface(),
1130 dispatcher(),
1131 metrics(),
1132 manager()));
1133 MockServiceRefPtr s_not_in_group(
1134 new NiceMock<MockService>(control_interface(),
1135 dispatcher(),
1136 metrics(),
1137 manager()));
1138 MockServiceRefPtr s_configure_fail(
1139 new NiceMock<MockService>(control_interface(),
1140 dispatcher(),
1141 metrics(),
1142 manager()));
1143 MockServiceRefPtr s_configure_succeed(
1144 new NiceMock<MockService>(control_interface(),
1145 dispatcher(),
1146 metrics(),
1147 manager()));
1148
1149 string entry_name("entry_name");
1150 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1151 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1152 .WillRepeatedly(Return("not_entry_name"));
1153 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1154 .WillRepeatedly(Return(entry_name));
1155 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1156 .WillRepeatedly(Return(entry_name));
1157
1158 manager()->RegisterService(s_not_in_profile);
1159 manager()->RegisterService(s_not_in_group);
1160 manager()->RegisterService(s_configure_fail);
1161 manager()->RegisterService(s_configure_succeed);
1162
1163 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001164 new StrictMock<MockProfile>(
1165 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001166 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001167 new StrictMock<MockProfile>(
1168 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001169
1170 s_not_in_group->set_profile(profile1);
1171 s_configure_fail->set_profile(profile1);
1172 s_configure_succeed->set_profile(profile1);
1173
1174 AdoptProfile(manager(), profile0);
1175 AdoptProfile(manager(), profile1);
1176
1177 // No services are a member of this profile.
1178 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1179
1180 // No services that are members of this profile have this entry name.
1181 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1182
1183 // Only services that are members of the profile and group will be abandoned.
1184 EXPECT_CALL(*profile1.get(),
1185 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1186 EXPECT_CALL(*profile1.get(),
1187 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1188 EXPECT_CALL(*profile1.get(),
1189 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1190 .WillOnce(Return(true));
1191 EXPECT_CALL(*profile1.get(),
1192 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1193 .WillOnce(Return(true));
1194
1195 // Never allow services to re-join profile1.
1196 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1197 .WillRepeatedly(Return(false));
1198
1199 // Only allow one of the members of the profile and group to successfully
1200 // join profile0.
1201 EXPECT_CALL(*profile0.get(),
1202 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1203 EXPECT_CALL(*profile0.get(),
1204 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1205 EXPECT_CALL(*profile0.get(),
1206 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1207 .WillOnce(Return(false));
1208 EXPECT_CALL(*profile0.get(),
1209 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1210 .WillOnce(Return(true));
1211
1212 // Expect the failed-to-configure service to have Unload() called on it.
1213 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1214 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1215 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1216 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1217
1218 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1219
1220 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1221 EXPECT_EQ(profile1, s_not_in_group->profile());
1222 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1223
1224 // Since we are using a MockProfile, the profile does not actually change,
1225 // since ConfigureService was not actually called on the service.
1226 EXPECT_EQ(profile1, s_configure_succeed->profile());
1227}
1228
Paul Stewart65512e12012-03-26 18:01:08 -07001229TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1230 MockServiceRefPtr s_will_remove0(
1231 new NiceMock<MockService>(control_interface(),
1232 dispatcher(),
1233 metrics(),
1234 manager()));
1235 MockServiceRefPtr s_will_remove1(
1236 new NiceMock<MockService>(control_interface(),
1237 dispatcher(),
1238 metrics(),
1239 manager()));
1240 MockServiceRefPtr s_will_not_remove0(
1241 new NiceMock<MockService>(control_interface(),
1242 dispatcher(),
1243 metrics(),
1244 manager()));
1245 MockServiceRefPtr s_will_not_remove1(
1246 new NiceMock<MockService>(control_interface(),
1247 dispatcher(),
1248 metrics(),
1249 manager()));
1250
1251 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1252 .Times(4); // Once for each registration.
1253
1254 string entry_name("entry_name");
1255 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1256 .WillRepeatedly(Return(entry_name));
1257 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1258 .WillRepeatedly(Return(entry_name));
1259 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1260 .WillRepeatedly(Return(entry_name));
1261 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1262 .WillRepeatedly(Return(entry_name));
1263
1264 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001265 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001266 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001267 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001268 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001269 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001270 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001271 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001272
1273 // One for each service added above.
1274 ASSERT_EQ(4, manager()->services_.size());
1275
1276 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001277 new StrictMock<MockProfile>(
1278 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001279
1280 s_will_remove0->set_profile(profile);
1281 s_will_remove1->set_profile(profile);
1282 s_will_not_remove0->set_profile(profile);
1283 s_will_not_remove1->set_profile(profile);
1284
1285 AdoptProfile(manager(), profile);
1286
1287 // Deny any of the services re-entry to the profile.
1288 EXPECT_CALL(*profile, ConfigureService(_))
1289 .WillRepeatedly(Return(false));
1290
1291 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1292 .WillOnce(Return(true));
1293 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1294 .WillOnce(Return(true));
1295 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1296 .WillOnce(Return(true));
1297 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1298 .WillOnce(Return(true));
1299
1300 EXPECT_CALL(*s_will_remove0, Unload())
1301 .WillOnce(Return(true));
1302 EXPECT_CALL(*s_will_remove1, Unload())
1303 .WillOnce(Return(true));
1304 EXPECT_CALL(*s_will_not_remove0, Unload())
1305 .WillOnce(Return(false));
1306 EXPECT_CALL(*s_will_not_remove1, Unload())
1307 .WillOnce(Return(false));
1308
1309
1310 // This will cause all the profiles to be unloaded.
1311 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1312
1313 // 2 of the 4 services added above should have been unregistered and
1314 // removed, leaving 2.
1315 EXPECT_EQ(2, manager()->services_.size());
1316 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1317 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1318}
1319
1320TEST_F(ManagerTest, PopProfileWithUnload) {
1321 MockServiceRefPtr s_will_remove0(
1322 new NiceMock<MockService>(control_interface(),
1323 dispatcher(),
1324 metrics(),
1325 manager()));
1326 MockServiceRefPtr s_will_remove1(
1327 new NiceMock<MockService>(control_interface(),
1328 dispatcher(),
1329 metrics(),
1330 manager()));
1331 MockServiceRefPtr s_will_not_remove0(
1332 new NiceMock<MockService>(control_interface(),
1333 dispatcher(),
1334 metrics(),
1335 manager()));
1336 MockServiceRefPtr s_will_not_remove1(
1337 new NiceMock<MockService>(control_interface(),
1338 dispatcher(),
1339 metrics(),
1340 manager()));
1341
1342 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1343 .Times(5); // Once for each registration, and one after profile pop.
1344
1345 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001346 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001347 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001348 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001349 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001350 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001351 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001352 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001353
1354 // One for each service added above.
1355 ASSERT_EQ(4, manager()->services_.size());
1356
1357 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001358 new StrictMock<MockProfile>(
1359 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001360 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001361 new StrictMock<MockProfile>(
1362 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001363
1364 s_will_remove0->set_profile(profile1);
1365 s_will_remove1->set_profile(profile1);
1366 s_will_not_remove0->set_profile(profile1);
1367 s_will_not_remove1->set_profile(profile1);
1368
1369 AdoptProfile(manager(), profile0);
1370 AdoptProfile(manager(), profile1);
1371
1372 // Deny any of the services entry to profile0, so they will all be unloaded.
1373 EXPECT_CALL(*profile0, ConfigureService(_))
1374 .WillRepeatedly(Return(false));
1375
1376 EXPECT_CALL(*s_will_remove0, Unload())
1377 .WillOnce(Return(true));
1378 EXPECT_CALL(*s_will_remove1, Unload())
1379 .WillOnce(Return(true));
1380 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001381 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001382 EXPECT_CALL(*s_will_not_remove1, Unload())
1383 .WillOnce(Return(false));
1384
Philipp Neubeck79173602012-11-13 21:10:09 +01001385 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1386 // profile list.
1387 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1388 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1389
Paul Stewart65512e12012-03-26 18:01:08 -07001390 // This will pop profile1, which should cause all our profiles to unload.
1391 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001392 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001393
1394 // 2 of the 4 services added above should have been unregistered and
1395 // removed, leaving 2.
1396 EXPECT_EQ(2, manager()->services_.size());
1397 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1398 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001399
1400 // Expect the unloaded services to lose their profile reference.
1401 EXPECT_FALSE(s_will_remove0->profile());
1402 EXPECT_FALSE(s_will_remove1->profile());
1403
1404 // If we explicitly deregister a service, the effect should be the same
1405 // with respect to the profile reference.
1406 ASSERT_TRUE(s_will_not_remove0->profile());
1407 manager()->DeregisterService(s_will_not_remove0);
1408 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001409}
1410
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001411TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001412 {
1413 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001414 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1415 flimflam::kOfflineModeProperty,
1416 PropertyStoreTest::kBoolV,
1417 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001418 }
1419 {
1420 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001421 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1422 flimflam::kCountryProperty,
1423 PropertyStoreTest::kStringV,
1424 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001425 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001426 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001427 {
1428 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001429 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1430 flimflam::kCountryProperty,
1431 PropertyStoreTest::kBoolV,
1432 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001433 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001434 }
1435 {
1436 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001437 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1438 flimflam::kOfflineModeProperty,
1439 PropertyStoreTest::kStringV,
1440 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001441 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001442 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001443 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001444 {
1445 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001446 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001447 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001448 flimflam::kEnabledTechnologiesProperty,
1449 PropertyStoreTest::kStringsV,
1450 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001451 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001452 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001453}
1454
mukesh agrawal32399322011-09-01 10:53:43 -07001455TEST_F(ManagerTest, RequestScan) {
1456 {
1457 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001458 manager()->RegisterDevice(mock_devices_[0].get());
1459 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001460 EXPECT_CALL(*mock_devices_[0], technology())
1461 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie68d41092013-04-02 12:56:02 -07001462 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _));
Joshua Krollda798622012-06-05 12:30:48 -07001463 EXPECT_CALL(*mock_devices_[1], technology())
1464 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie68d41092013-04-02 12:56:02 -07001465 EXPECT_CALL(*mock_devices_[1], Scan(_, _)).Times(0);
1466 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001467 }
1468
1469 {
1470 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001471 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001472 EXPECT_EQ(Error::kInvalidArguments, error.type());
1473 }
1474}
1475
Darin Petkovb65c2452012-02-23 15:17:06 +01001476TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001477 KeyValueStore args;
1478 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001479 manager()->GetService(args, &e);
1480 EXPECT_EQ(Error::kInvalidArguments, e.type());
1481 EXPECT_EQ("must specify service type", e.message());
1482}
1483
1484TEST_F(ManagerTest, GetServiceUnknownType) {
1485 KeyValueStore args;
1486 Error e;
1487 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1488 manager()->GetService(args, &e);
1489 EXPECT_EQ(Error::kNotSupported, e.type());
1490 EXPECT_EQ("service type is unsupported", e.message());
1491}
1492
Paul Stewart35eff132013-04-12 12:08:40 -07001493TEST_F(ManagerTest, GetServiceEthernetEap) {
1494 KeyValueStore args;
1495 Error e;
1496 ServiceRefPtr service;
1497 args.SetString(flimflam::kTypeProperty, kTypeEthernetEap);
1498 SetEapProviderService(service);
1499 EXPECT_EQ(service, manager()->GetService(args, &e));
1500 EXPECT_TRUE(e.IsSuccess());
1501}
1502
Darin Petkovb65c2452012-02-23 15:17:06 +01001503TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001504 KeyValueStore args;
1505 Error e;
1506 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001507 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001508 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001509 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001510 manager()->GetService(args, &e);
1511 EXPECT_TRUE(e.IsSuccess());
1512}
1513
Darin Petkov33af05c2012-02-28 10:10:30 +01001514TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1515 KeyValueStore args;
1516 Error e;
1517 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001518 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001519 new StrictMock<MockProfile>(
1520 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001521 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001522 ServiceRefPtr service = manager()->GetService(args, &e);
1523 EXPECT_EQ(Error::kNotSupported, e.type());
1524 EXPECT_FALSE(service);
1525}
1526
Darin Petkovb65c2452012-02-23 15:17:06 +01001527TEST_F(ManagerTest, GetServiceVPN) {
1528 KeyValueStore args;
1529 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001530 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001531 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001532 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001533 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001534 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001535 new StrictMock<MockProfile>(
1536 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001537 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001538
1539#if defined(DISABLE_VPN)
1540
1541 ServiceRefPtr service = manager()->GetService(args, &e);
1542 EXPECT_EQ(Error::kNotSupported, e.type());
1543 EXPECT_FALSE(service);
1544
1545#else
1546
Paul Stewart7f5ad572012-06-04 15:18:54 -07001547 ServiceRefPtr updated_service;
1548 EXPECT_CALL(*profile, UpdateService(_))
1549 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1550 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001551 EXPECT_CALL(*profile, LoadService(_))
1552 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001553 EXPECT_CALL(*profile, ConfigureService(_))
1554 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001555 ServiceRefPtr service = manager()->GetService(args, &e);
1556 EXPECT_TRUE(e.IsSuccess());
1557 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001558 EXPECT_EQ(service, updated_service);
1559 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001560
1561#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001562}
1563
Darin Petkovc63dcf02012-05-24 11:51:43 +02001564TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1565 KeyValueStore args;
1566 Error e;
1567 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1568 ServiceRefPtr service = manager()->GetService(args, &e);
1569 EXPECT_EQ(Error::kInvalidArguments, e.type());
1570 EXPECT_EQ("Missing WiMAX network id.", e.message());
1571 EXPECT_FALSE(service);
1572}
1573
Darin Petkovd1cd7972012-05-22 15:26:15 +02001574TEST_F(ManagerTest, GetServiceWiMax) {
1575 KeyValueStore args;
1576 Error e;
1577 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001578 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1579 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1580 ServiceRefPtr service = manager()->GetService(args, &e);
1581 EXPECT_TRUE(e.IsSuccess());
1582 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001583}
1584
Paul Stewart7f61e522012-03-22 11:13:45 -07001585TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1586 // Manager calls ActiveProfile() so we need at least one profile installed.
1587 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001588 new NiceMock<MockProfile>(
1589 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001590 AdoptProfile(manager(), profile);
1591
1592 KeyValueStore args;
1593 args.SetString(flimflam::kProfileProperty, "xxx");
1594 Error error;
1595 manager()->ConfigureService(args, &error);
1596 EXPECT_EQ(Error::kInvalidArguments, error.type());
1597 EXPECT_EQ("Invalid profile name xxx", error.message());
1598}
1599
1600TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1601 // Manager calls ActiveProfile() so we need at least one profile installed.
1602 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001603 new NiceMock<MockProfile>(
1604 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001605 AdoptProfile(manager(), profile);
1606
1607 KeyValueStore args;
1608 Error error;
1609 manager()->ConfigureService(args, &error);
1610 EXPECT_EQ(Error::kInvalidArguments, error.type());
1611 EXPECT_EQ("must specify service type", error.message());
1612}
1613
1614// A registered service in the ephemeral profile should be moved to the
1615// active profile as a part of configuration if no profile was explicitly
1616// specified.
1617TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1618 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001619 new NiceMock<MockProfile>(
1620 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001621
1622 AdoptProfile(manager(), profile); // This is now the active profile.
1623
Paul Stewartd2e1c362013-03-03 19:06:07 -08001624 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001625 scoped_refptr<MockWiFiService> service(
1626 new NiceMock<MockWiFiService>(control_interface(),
1627 dispatcher(),
1628 metrics(),
1629 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001630 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001631 ssid,
1632 "",
1633 "",
1634 false));
1635
1636 manager()->RegisterService(service);
1637 service->set_profile(GetEphemeralProfile(manager()));
1638
Paul Stewart3c504012013-01-17 17:49:58 -08001639 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001640 .WillOnce(Return(service));
1641 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1642 .WillOnce(Return(true));
1643 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1644 .WillOnce(Return(true));
1645
1646 KeyValueStore args;
1647 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1648 Error error;
1649 manager()->ConfigureService(args, &error);
1650 EXPECT_TRUE(error.IsSuccess());
1651}
1652
Paul Stewart2c575d22012-12-07 12:28:57 -08001653// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001654// specify a profile, it should be moved from the profile it was previously
1655// in to the specified profile if one was requested.
1656TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1657 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001658 new NiceMock<MockProfile>(
1659 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001660 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001661 new NiceMock<MockProfile>(
1662 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001663
1664 const string kProfileName0 = "profile0";
1665 const string kProfileName1 = "profile1";
1666
1667 EXPECT_CALL(*profile0, GetRpcIdentifier())
1668 .WillRepeatedly(Return(kProfileName0));
1669 EXPECT_CALL(*profile1, GetRpcIdentifier())
1670 .WillRepeatedly(Return(kProfileName1));
1671
1672 AdoptProfile(manager(), profile0);
1673 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1674
Paul Stewartd2e1c362013-03-03 19:06:07 -08001675 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001676 scoped_refptr<MockWiFiService> service(
1677 new NiceMock<MockWiFiService>(control_interface(),
1678 dispatcher(),
1679 metrics(),
1680 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001681 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001682 ssid,
1683 "",
1684 "",
1685 false));
1686
1687 manager()->RegisterService(service);
1688 service->set_profile(profile1);
1689
Paul Stewart3c504012013-01-17 17:49:58 -08001690 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001691 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001692 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1693 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001694 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1695 .WillOnce(Return(true));
1696 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1697 .WillOnce(Return(true));
1698 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1699 .WillOnce(Return(true));
1700
1701 KeyValueStore args;
1702 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1703 args.SetString(flimflam::kProfileProperty, kProfileName0);
1704 Error error;
1705 manager()->ConfigureService(args, &error);
1706 EXPECT_TRUE(error.IsSuccess());
1707 service->set_profile(NULL); // Breaks refcounting loop.
1708}
1709
Paul Stewart2c575d22012-12-07 12:28:57 -08001710// If we configure a service that is already a member of the specified
1711// profile, the Manager should not call LoadService or AdoptService again
1712// on this service.
1713TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1714 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001715 new NiceMock<MockProfile>(
1716 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001717
1718 const string kProfileName0 = "profile0";
1719
1720 EXPECT_CALL(*profile0, GetRpcIdentifier())
1721 .WillRepeatedly(Return(kProfileName0));
1722
1723 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1724
Paul Stewartd2e1c362013-03-03 19:06:07 -08001725 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001726 scoped_refptr<MockWiFiService> service(
1727 new NiceMock<MockWiFiService>(control_interface(),
1728 dispatcher(),
1729 metrics(),
1730 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001731 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001732 ssid,
1733 "",
1734 "",
1735 false));
1736
1737 manager()->RegisterService(service);
1738 service->set_profile(profile0);
1739
Paul Stewart3c504012013-01-17 17:49:58 -08001740 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001741 .WillOnce(Return(service));
1742 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1743 .Times(0);
1744 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1745 .WillOnce(Return(true));
1746 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1747 .Times(0);
1748
1749 KeyValueStore args;
1750 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1751 args.SetString(flimflam::kProfileProperty, kProfileName0);
1752 Error error;
1753 manager()->ConfigureService(args, &error);
1754 EXPECT_TRUE(error.IsSuccess());
1755 service->set_profile(NULL); // Breaks refcounting loop.
1756}
1757
Paul Stewart7f61e522012-03-22 11:13:45 -07001758// An unregistered service should remain unregistered, but its contents should
1759// be saved to the specified profile nonetheless.
1760TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1761 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001762 new NiceMock<MockProfile>(
1763 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001764 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001765 new NiceMock<MockProfile>(
1766 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001767
1768 const string kProfileName0 = "profile0";
1769 const string kProfileName1 = "profile1";
1770
1771 EXPECT_CALL(*profile0, GetRpcIdentifier())
1772 .WillRepeatedly(Return(kProfileName0));
1773 EXPECT_CALL(*profile1, GetRpcIdentifier())
1774 .WillRepeatedly(Return(kProfileName1));
1775
1776 AdoptProfile(manager(), profile0);
1777 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1778
Paul Stewartd2e1c362013-03-03 19:06:07 -08001779 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001780 scoped_refptr<MockWiFiService> service(
1781 new NiceMock<MockWiFiService>(control_interface(),
1782 dispatcher(),
1783 metrics(),
1784 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001785 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001786 ssid,
1787 "",
1788 "",
1789 false));
1790
1791 service->set_profile(profile1);
1792
Paul Stewart3c504012013-01-17 17:49:58 -08001793 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001794 .WillOnce(Return(service));
1795 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1796 .WillOnce(Return(true));
1797 EXPECT_CALL(*profile0, AdoptService(_))
1798 .Times(0);
1799 EXPECT_CALL(*profile1, AdoptService(_))
1800 .Times(0);
1801
1802 KeyValueStore args;
1803 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1804 args.SetString(flimflam::kProfileProperty, kProfileName0);
1805 Error error;
1806 manager()->ConfigureService(args, &error);
1807 EXPECT_TRUE(error.IsSuccess());
1808}
1809
Paul Stewartd2e1c362013-03-03 19:06:07 -08001810TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1811 KeyValueStore args;
1812 Error error;
1813 ServiceRefPtr service =
1814 manager()->ConfigureServiceForProfile("", args, &error);
1815 EXPECT_EQ(Error::kNotSupported, error.type());
1816 EXPECT_EQ("This method only supports WiFi services", error.message());
1817 EXPECT_EQ(NULL, service.get());
1818}
1819
1820TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1821 KeyValueStore args;
1822 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1823 Error error;
1824 ServiceRefPtr service =
1825 manager()->ConfigureServiceForProfile("", args, &error);
1826 EXPECT_EQ(Error::kNotSupported, error.type());
1827 EXPECT_EQ("This method only supports WiFi services", error.message());
1828 EXPECT_EQ(NULL, service.get());
1829}
1830
1831TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1832 KeyValueStore args;
1833 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1834 Error error;
1835 ServiceRefPtr service =
1836 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1837 EXPECT_EQ(Error::kNotFound, error.type());
1838 EXPECT_EQ("Profile specified was not found", error.message());
1839 EXPECT_EQ(NULL, service.get());
1840}
1841
1842TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1843 const string kProfileName0 = "profile0";
1844 const string kProfileName1 = "profile1";
1845 scoped_refptr<MockProfile> profile0(
1846 AddNamedMockProfileToManager(manager(), kProfileName0));
1847
1848 KeyValueStore args;
1849 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1850 args.SetString(flimflam::kProfileProperty, kProfileName1);
1851 Error error;
1852 ServiceRefPtr service =
1853 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1854 EXPECT_EQ(Error::kInvalidArguments, error.type());
1855 EXPECT_EQ("Profile argument does not match that in "
1856 "the configuration arguments", error.message());
1857 EXPECT_EQ(NULL, service.get());
1858}
1859
1860TEST_F(ManagerTest,
1861 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1862 const string kProfileName0 = "profile0";
1863 scoped_refptr<MockProfile> profile0(
1864 AddNamedMockProfileToManager(manager(), kProfileName0));
1865 KeyValueStore args;
1866 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1867 args.SetString(flimflam::kProfileProperty, kProfileName0);
1868
1869 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1870 .WillOnce(Return(WiFiServiceRefPtr()));
1871 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1872 .WillOnce(Return(WiFiServiceRefPtr()));
1873 Error error;
1874 ServiceRefPtr service =
1875 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1876 // Since we didn't set the error in the GetService expectation above...
1877 EXPECT_TRUE(error.IsSuccess());
1878 EXPECT_EQ(NULL, service.get());
1879}
1880
1881TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1882 const string kProfileName0 = "profile0";
1883 scoped_refptr<MockProfile> profile0(
1884 AddNamedMockProfileToManager(manager(), kProfileName0));
1885
1886 KeyValueStore args;
1887 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1888
1889 scoped_refptr<MockWiFiService> mock_service(
1890 new NiceMock<MockWiFiService>(control_interface(),
1891 dispatcher(),
1892 metrics(),
1893 manager(),
1894 wifi_provider_,
1895 vector<uint8_t>(),
1896 flimflam::kModeManaged,
1897 flimflam::kSecurityNone,
1898 false));
1899 ServiceRefPtr mock_service_generic(mock_service.get());
1900 mock_service->set_profile(profile0);
1901 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1902 .WillOnce(Return(WiFiServiceRefPtr()));
1903 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1904 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1905 .WillOnce(Return(true));
1906 Error error;
1907 ServiceRefPtr service =
1908 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1909 EXPECT_TRUE(error.IsSuccess());
1910 EXPECT_EQ(mock_service.get(), service.get());
1911 mock_service->set_profile(NULL); // Breaks reference cycle.
1912}
1913
1914TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
1915 scoped_refptr<MockService> mock_service(
1916 new NiceMock<MockService>(control_interface(),
1917 dispatcher(),
1918 metrics(),
1919 manager()));
1920 const string kGUID = "a guid";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001921 mock_service->SetGuid(kGUID, NULL);
Paul Stewartd2e1c362013-03-03 19:06:07 -08001922 manager()->RegisterService(mock_service);
1923 ServiceRefPtr mock_service_generic(mock_service.get());
1924
1925 const string kProfileName = "profile";
1926 scoped_refptr<MockProfile> profile(
1927 AddNamedMockProfileToManager(manager(), kProfileName));
1928 mock_service->set_profile(profile);
1929
1930 EXPECT_CALL(*mock_service, technology())
1931 .WillOnce(Return(Technology::kCellular))
1932 .WillOnce(Return(Technology::kWifi));
1933
1934 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
1935 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1936 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1937
1938 KeyValueStore args;
1939 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1940 args.SetString(flimflam::kGuidProperty, kGUID);
1941
1942 // The first attempt should fail because the service reports a technology
1943 // other than "WiFi".
1944 {
1945 Error error;
1946 ServiceRefPtr service =
1947 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1948 EXPECT_EQ(NULL, service.get());
1949 EXPECT_EQ(Error::kNotSupported, error.type());
1950 EXPECT_EQ("This GUID matches a non-WiFi service", error.message());
1951 }
1952
1953 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1954 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1955
1956 {
1957 Error error;
1958 ServiceRefPtr service =
1959 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1960 EXPECT_TRUE(error.IsSuccess());
1961 EXPECT_EQ(mock_service.get(), service.get());
1962 EXPECT_EQ(profile.get(), service->profile().get());
1963 }
1964 mock_service->set_profile(NULL); // Breaks reference cycle.
1965}
1966
1967TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
1968 const string kProfileName = "profile";
1969 scoped_refptr<MockProfile> profile(
1970 AddNamedMockProfileToManager(manager(), kProfileName));
1971
1972 scoped_refptr<MockWiFiService> mock_service(
1973 new NiceMock<MockWiFiService>(control_interface(),
1974 dispatcher(),
1975 metrics(),
1976 manager(),
1977 wifi_provider_,
1978 vector<uint8_t>(),
1979 flimflam::kModeManaged,
1980 flimflam::kSecurityNone,
1981 false));
1982 mock_service->set_profile(profile);
1983 ServiceRefPtr mock_service_generic(mock_service.get());
1984
1985 KeyValueStore args;
1986 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1987 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1988 .WillOnce(Return(mock_service));
1989 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1990 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1991 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1992 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1993
1994 Error error;
1995 ServiceRefPtr service =
1996 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1997 EXPECT_TRUE(error.IsSuccess());
1998 EXPECT_EQ(mock_service.get(), service.get());
1999 EXPECT_EQ(profile.get(), service->profile().get());
2000 mock_service->set_profile(NULL); // Breaks reference cycle.
2001}
2002
2003TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
2004 const string kProfileName = "profile";
2005 scoped_refptr<MockProfile> profile(
2006 AddNamedMockProfileToManager(manager(), kProfileName));
2007
2008 scoped_refptr<MockWiFiService> mock_service(
2009 new NiceMock<MockWiFiService>(control_interface(),
2010 dispatcher(),
2011 metrics(),
2012 manager(),
2013 wifi_provider_,
2014 vector<uint8_t>(),
2015 flimflam::kModeManaged,
2016 flimflam::kSecurityNone,
2017 false));
2018 mock_service->set_profile(GetEphemeralProfile(manager()));
2019 ServiceRefPtr mock_service_generic(mock_service.get());
2020
2021 KeyValueStore args;
2022 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2023 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2024 .WillOnce(Return(mock_service));
2025 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2026 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2027 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2028
2029 Error error;
2030 ServiceRefPtr service =
2031 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2032 EXPECT_TRUE(error.IsSuccess());
2033 EXPECT_EQ(mock_service.get(), service.get());
2034 EXPECT_EQ(profile.get(), service->profile().get());
2035 mock_service->set_profile(NULL); // Breaks reference cycle.
2036}
2037
2038TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2039 const string kProfileName0 = "profile0";
2040 scoped_refptr<MockProfile> profile0(
2041 AddNamedMockProfileToManager(manager(), kProfileName0));
2042 const string kProfileName1 = "profile1";
2043 scoped_refptr<MockProfile> profile1(
2044 AddNamedMockProfileToManager(manager(), kProfileName1));
2045
2046 scoped_refptr<MockWiFiService> mock_service(
2047 new NiceMock<MockWiFiService>(control_interface(),
2048 dispatcher(),
2049 metrics(),
2050 manager(),
2051 wifi_provider_,
2052 vector<uint8_t>(),
2053 flimflam::kModeManaged,
2054 flimflam::kSecurityNone,
2055 false));
2056 manager()->RegisterService(mock_service);
2057 mock_service->set_profile(profile0);
2058 ServiceRefPtr mock_service_generic(mock_service.get());
2059
2060 KeyValueStore args;
2061 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2062 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2063 .WillOnce(Return(mock_service));
2064 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2065 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2066 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2067 // This happens once to make the service loadable for the ConfigureService
2068 // below, and a second time after the service is modified.
2069 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2070 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2071 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2072 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2073
2074 Error error;
2075 ServiceRefPtr service =
2076 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2077 EXPECT_TRUE(error.IsSuccess());
2078 EXPECT_EQ(mock_service.get(), service.get());
2079 mock_service->set_profile(NULL); // Breaks reference cycle.
2080}
2081
2082TEST_F(ManagerTest,
2083 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2084 const string kProfileName0 = "profile0";
2085 scoped_refptr<MockProfile> profile0(
2086 AddNamedMockProfileToManager(manager(), kProfileName0));
2087 const string kProfileName1 = "profile1";
2088 scoped_refptr<MockProfile> profile1(
2089 AddNamedMockProfileToManager(manager(), kProfileName1));
2090
2091 scoped_refptr<MockWiFiService> matching_service(
2092 new StrictMock<MockWiFiService>(control_interface(),
2093 dispatcher(),
2094 metrics(),
2095 manager(),
2096 wifi_provider_,
2097 vector<uint8_t>(),
2098 flimflam::kModeManaged,
2099 flimflam::kSecurityNone,
2100 false));
2101 matching_service->set_profile(profile1);
2102
2103 // We need to get rid of our reference to this mock service as soon
2104 // as Manager::ConfigureServiceForProfile() takes a reference in its
2105 // call to WiFiProvider::CreateTemporaryService(). This way the
2106 // latter function can keep a DCHECK(service->HasOneRef() even in
2107 // unit tests.
2108 temp_mock_service_ =
2109 new NiceMock<MockWiFiService>(control_interface(),
2110 dispatcher(),
2111 metrics(),
2112 manager(),
2113 wifi_provider_,
2114 vector<uint8_t>(),
2115 flimflam::kModeManaged,
2116 flimflam::kSecurityNone,
2117 false);
2118
2119 // Only hold a pointer here so we don't affect the refcount.
2120 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2121
2122 KeyValueStore args;
2123 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2124 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2125 .WillOnce(Return(matching_service));
2126 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2127 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2128 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2129 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2130 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2131 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2132 .Times(1);
2133 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2134 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2135
2136 Error error;
2137 ServiceRefPtr service =
2138 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2139 EXPECT_TRUE(error.IsSuccess());
2140 EXPECT_EQ(NULL, service.get());
2141 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2142}
2143
Paul Stewart7a20aa42013-01-17 12:21:41 -08002144TEST_F(ManagerTest, FindMatchingService) {
2145 KeyValueStore args;
2146 {
2147 Error error;
2148 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2149 EXPECT_EQ(Error::kNotFound, error.type());
2150 }
2151
2152 scoped_refptr<MockService> mock_service0(
2153 new NiceMock<MockService>(control_interface(),
2154 dispatcher(),
2155 metrics(),
2156 manager()));
2157 scoped_refptr<MockService> mock_service1(
2158 new NiceMock<MockService>(control_interface(),
2159 dispatcher(),
2160 metrics(),
2161 manager()));
2162 manager()->RegisterService(mock_service0);
2163 manager()->RegisterService(mock_service1);
2164 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2165 .WillOnce(Return(true))
2166 .WillRepeatedly(Return(false));
2167 {
2168 Error error;
2169 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2170 EXPECT_TRUE(error.IsSuccess());
2171 }
2172 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2173 .WillOnce(Return(true))
2174 .WillRepeatedly(Return(false));
2175 {
2176 Error error;
2177 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2178 EXPECT_TRUE(error.IsSuccess());
2179 }
2180 {
2181 Error error;
2182 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2183 EXPECT_EQ(Error::kNotFound, error.type());
2184 }
2185}
2186
Paul Stewart22aa71b2011-09-16 12:15:11 -07002187TEST_F(ManagerTest, TechnologyOrder) {
2188 Error error;
2189 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2190 string(flimflam::kTypeWifi), &error);
2191 ASSERT_TRUE(error.IsSuccess());
2192 EXPECT_EQ(manager()->GetTechnologyOrder(),
2193 string(flimflam::kTypeEthernet) + "," +
2194 string(flimflam::kTypeWifi));
2195
2196 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2197 string(flimflam::kTypeWifi), &error);
2198 ASSERT_FALSE(error.IsSuccess());
2199 EXPECT_EQ(Error::kInvalidArguments, error.type());
2200 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2201 string(flimflam::kTypeWifi),
2202 manager()->GetTechnologyOrder());
2203}
2204
2205TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002206 // TODO(quiche): Some of these tests would probably fit better in
2207 // service_unittest, since the actual comparison of Services is
2208 // implemented in Service. (crosbug.com/23370)
2209
Paul Stewart22aa71b2011-09-16 12:15:11 -07002210 scoped_refptr<MockService> mock_service0(
2211 new NiceMock<MockService>(control_interface(),
2212 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002213 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002214 manager()));
2215 scoped_refptr<MockService> mock_service1(
2216 new NiceMock<MockService>(control_interface(),
2217 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002218 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002219 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002220
2221 manager()->RegisterService(mock_service0);
2222 manager()->RegisterService(mock_service1);
2223
Darin Petkov457728b2013-01-09 09:49:08 +01002224 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002225 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2226
2227 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002228 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002229 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2230
2231 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002232 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002233 manager()->UpdateService(mock_service1);
2234 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2235
2236 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002237 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002238 manager()->UpdateService(mock_service0);
2239 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2240
2241 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002242 EXPECT_CALL(*mock_service0.get(), technology())
2243 .WillRepeatedly(Return((Technology::kWifi)));
2244 EXPECT_CALL(*mock_service1.get(), technology())
2245 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002246
2247 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002248 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002249 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002250 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2251
2252 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2253 string(flimflam::kTypeEthernet), &error);
2254 EXPECT_TRUE(error.IsSuccess());
2255 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2256
Gaurav Shah435de2c2011-11-17 19:01:07 -08002257 // Priority.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002258 mock_service0->SetPriority(1, NULL);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002259 manager()->UpdateService(mock_service0);
2260 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2261
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002262 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002263 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002264 manager()->UpdateService(mock_service1);
2265 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2266
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002267 // Auto-connect.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002268 mock_service0->SetAutoConnect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002269 manager()->UpdateService(mock_service0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002270 mock_service1->SetAutoConnect(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002271 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002272 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2273
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002274 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2275 // to any of the others below, so we reset to the default state after
2276 // testing.
2277 EXPECT_CALL(*mock_service1.get(),
2278 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2279 .WillOnce(Return(true))
2280 .WillRepeatedly(Return(false));
2281 manager()->UpdateService(mock_service1);
2282 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2283 manager()->UpdateService(mock_service0);
2284 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2285
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002286 // Connectable.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002287 mock_service1->SetConnectable(true);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002288 manager()->UpdateService(mock_service1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002289 mock_service0->SetConnectable(false);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002290 manager()->UpdateService(mock_service0);
2291 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2292
2293 // IsFailed.
2294 EXPECT_CALL(*mock_service0.get(), state())
2295 .WillRepeatedly(Return(Service::kStateIdle));
2296 EXPECT_CALL(*mock_service0.get(), IsFailed())
2297 .WillRepeatedly(Return(false));
2298 manager()->UpdateService(mock_service0);
2299 EXPECT_CALL(*mock_service0.get(), state())
2300 .WillRepeatedly(Return(Service::kStateFailure));
2301 EXPECT_CALL(*mock_service1.get(), IsFailed())
2302 .WillRepeatedly(Return(true));
2303 manager()->UpdateService(mock_service1);
2304 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2305
2306 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002307 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002308 .WillRepeatedly(Return(Service::kStateAssociating));
2309 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002310 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002311 manager()->UpdateService(mock_service1);
2312 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2313
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002314 // Connected.
2315 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002316 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002317 EXPECT_CALL(*mock_service0.get(), IsConnected())
2318 .WillRepeatedly(Return(true));
2319 manager()->UpdateService(mock_service0);
2320 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2321
Paul Stewarta121c442012-06-09 14:12:58 -07002322 // Portal.
2323 EXPECT_CALL(*mock_service1.get(), state())
2324 .WillRepeatedly(Return(Service::kStateConnected));
2325 EXPECT_CALL(*mock_service1.get(), IsConnected())
2326 .WillRepeatedly(Return(true));
2327 manager()->UpdateService(mock_service1);
2328 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2329
Paul Stewart22aa71b2011-09-16 12:15:11 -07002330 manager()->DeregisterService(mock_service0);
2331 manager()->DeregisterService(mock_service1);
2332}
2333
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002334TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002335 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002336 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002337
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002338 scoped_refptr<MockService> mock_service0(
2339 new NiceMock<MockService>(control_interface(),
2340 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002341 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002342 manager()));
2343 scoped_refptr<MockService> mock_service1(
2344 new NiceMock<MockService>(control_interface(),
2345 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002346 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002347 manager()));
2348
2349 scoped_refptr<MockConnection> mock_connection0(
2350 new NiceMock<MockConnection>(device_info_.get()));
2351 scoped_refptr<MockConnection> mock_connection1(
2352 new NiceMock<MockConnection>(device_info_.get()));
2353
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002354 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002355 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002356 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002357 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002358 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002359 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002360
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002361 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002362 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002363
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002364 mock_service1->SetPriority(1, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002365 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002366 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002367
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002368 mock_service1->SetPriority(0, NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002369 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002370 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002371
Paul Stewartce4ec192012-03-14 12:53:46 -07002372 mock_service0->set_mock_connection(mock_connection0);
2373 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002374
2375 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002376 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002377 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002378
Darin Petkova5e07ef2012-07-09 14:27:57 +02002379 ServiceWatcher service_watcher;
2380 int tag =
2381 manager()->RegisterDefaultServiceCallback(
2382 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2383 service_watcher.AsWeakPtr()));
2384 EXPECT_EQ(1, tag);
2385
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002386 mock_service1->SetPriority(1, NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002387 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2388 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002389 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002390 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002391 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002392
Darin Petkova5e07ef2012-07-09 14:27:57 +02002393 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002394 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002395 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002396 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002397 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002398 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002399 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002400
Paul Stewartce4ec192012-03-14 12:53:46 -07002401 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002402 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002403 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002404 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002405
2406 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002407 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002408}
2409
Darin Petkova5e07ef2012-07-09 14:27:57 +02002410TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2411 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2412 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2413
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002414 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002415 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002416
2417 scoped_refptr<MockService> mock_service(
2418 new NiceMock<MockService>(
2419 control_interface(), dispatcher(), metrics(), manager()));
2420 ServiceRefPtr service = mock_service;
2421 ServiceRefPtr null_service;
2422
2423 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2424 manager()->NotifyDefaultServiceChanged(null_service);
2425
2426 ServiceWatcher service_watcher1;
2427 ServiceWatcher service_watcher2;
2428 int tag1 =
2429 manager()->RegisterDefaultServiceCallback(
2430 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2431 service_watcher1.AsWeakPtr()));
2432 EXPECT_EQ(1, tag1);
2433 int tag2 =
2434 manager()->RegisterDefaultServiceCallback(
2435 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2436 service_watcher2.AsWeakPtr()));
2437 EXPECT_EQ(2, tag2);
2438
2439 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2440 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2441 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2442 manager()->NotifyDefaultServiceChanged(null_service);
2443
2444 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2445 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2446 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2447 manager()->NotifyDefaultServiceChanged(mock_service);
2448
2449 manager()->DeregisterDefaultServiceCallback(tag1);
2450 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2451 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2452 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2453 manager()->NotifyDefaultServiceChanged(mock_service);
2454 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2455
2456 manager()->DeregisterDefaultServiceCallback(tag2);
2457 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2458 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2459 manager()->NotifyDefaultServiceChanged(mock_service);
2460
2461 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2462 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2463}
2464
Gaurav Shah435de2c2011-11-17 19:01:07 -08002465TEST_F(ManagerTest, AvailableTechnologies) {
2466 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2467 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002468 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002469 manager(),
2470 "null4",
2471 "addr4",
2472 0));
2473 manager()->RegisterDevice(mock_devices_[0]);
2474 manager()->RegisterDevice(mock_devices_[1]);
2475 manager()->RegisterDevice(mock_devices_[2]);
2476 manager()->RegisterDevice(mock_devices_[3]);
2477
2478 ON_CALL(*mock_devices_[0].get(), technology())
2479 .WillByDefault(Return(Technology::kEthernet));
2480 ON_CALL(*mock_devices_[1].get(), technology())
2481 .WillByDefault(Return(Technology::kWifi));
2482 ON_CALL(*mock_devices_[2].get(), technology())
2483 .WillByDefault(Return(Technology::kCellular));
2484 ON_CALL(*mock_devices_[3].get(), technology())
2485 .WillByDefault(Return(Technology::kWifi));
2486
2487 set<string> expected_technologies;
2488 expected_technologies.insert(Technology::NameFromIdentifier(
2489 Technology::kEthernet));
2490 expected_technologies.insert(Technology::NameFromIdentifier(
2491 Technology::kWifi));
2492 expected_technologies.insert(Technology::NameFromIdentifier(
2493 Technology::kCellular));
2494 Error error;
2495 vector<string> technologies = manager()->AvailableTechnologies(&error);
2496
2497 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2498 ContainerEq(expected_technologies));
2499}
2500
2501TEST_F(ManagerTest, ConnectedTechnologies) {
2502 scoped_refptr<MockService> connected_service1(
2503 new NiceMock<MockService>(control_interface(),
2504 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002505 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002506 manager()));
2507 scoped_refptr<MockService> connected_service2(
2508 new NiceMock<MockService>(control_interface(),
2509 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002510 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002511 manager()));
2512 scoped_refptr<MockService> disconnected_service1(
2513 new NiceMock<MockService>(control_interface(),
2514 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002515 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002516 manager()));
2517 scoped_refptr<MockService> disconnected_service2(
2518 new NiceMock<MockService>(control_interface(),
2519 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002520 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002521 manager()));
2522
2523 ON_CALL(*connected_service1.get(), IsConnected())
2524 .WillByDefault(Return(true));
2525 ON_CALL(*connected_service2.get(), IsConnected())
2526 .WillByDefault(Return(true));
2527
2528 manager()->RegisterService(connected_service1);
2529 manager()->RegisterService(connected_service2);
2530 manager()->RegisterService(disconnected_service1);
2531 manager()->RegisterService(disconnected_service2);
2532
2533 manager()->RegisterDevice(mock_devices_[0]);
2534 manager()->RegisterDevice(mock_devices_[1]);
2535 manager()->RegisterDevice(mock_devices_[2]);
2536 manager()->RegisterDevice(mock_devices_[3]);
2537
2538 ON_CALL(*mock_devices_[0].get(), technology())
2539 .WillByDefault(Return(Technology::kEthernet));
2540 ON_CALL(*mock_devices_[1].get(), technology())
2541 .WillByDefault(Return(Technology::kWifi));
2542 ON_CALL(*mock_devices_[2].get(), technology())
2543 .WillByDefault(Return(Technology::kCellular));
2544 ON_CALL(*mock_devices_[3].get(), technology())
2545 .WillByDefault(Return(Technology::kWifi));
2546
2547 mock_devices_[0]->SelectService(connected_service1);
2548 mock_devices_[1]->SelectService(disconnected_service1);
2549 mock_devices_[2]->SelectService(disconnected_service2);
2550 mock_devices_[3]->SelectService(connected_service2);
2551
2552 set<string> expected_technologies;
2553 expected_technologies.insert(Technology::NameFromIdentifier(
2554 Technology::kEthernet));
2555 expected_technologies.insert(Technology::NameFromIdentifier(
2556 Technology::kWifi));
2557 Error error;
2558
2559 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2560 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2561 ContainerEq(expected_technologies));
2562}
2563
2564TEST_F(ManagerTest, DefaultTechnology) {
2565 scoped_refptr<MockService> connected_service(
2566 new NiceMock<MockService>(control_interface(),
2567 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002568 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002569 manager()));
2570 scoped_refptr<MockService> disconnected_service(
2571 new NiceMock<MockService>(control_interface(),
2572 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002573 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002574 manager()));
2575
2576 // Connected. WiFi.
2577 ON_CALL(*connected_service.get(), IsConnected())
2578 .WillByDefault(Return(true));
2579 ON_CALL(*connected_service.get(), state())
2580 .WillByDefault(Return(Service::kStateConnected));
2581 ON_CALL(*connected_service.get(), technology())
2582 .WillByDefault(Return(Technology::kWifi));
2583
2584 // Disconnected. Ethernet.
2585 ON_CALL(*disconnected_service.get(), technology())
2586 .WillByDefault(Return(Technology::kEthernet));
2587
2588 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002589 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002590 Error error;
2591 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2592
2593
2594 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002595 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002596 // Connected service should be brought to the front now.
2597 string expected_technology =
2598 Technology::NameFromIdentifier(Technology::kWifi);
2599 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2600}
2601
Paul Stewart212d60f2012-07-12 10:59:13 -07002602TEST_F(ManagerTest, Stop) {
2603 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002604 new NiceMock<MockProfile>(
2605 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002606 AdoptProfile(manager(), profile);
2607 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002608 new NiceMock<MockService>(control_interface(),
2609 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002610 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002611 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002612 manager()->RegisterService(service);
2613 manager()->RegisterDevice(mock_devices_[0]);
2614 EXPECT_CALL(*profile.get(),
2615 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2616 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002617 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002618 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2619 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002620 manager()->Stop();
2621}
2622
mukesh agrawal00917ce2011-11-22 23:56:55 +00002623TEST_F(ManagerTest, UpdateServiceConnected) {
2624 scoped_refptr<MockService> mock_service(
2625 new NiceMock<MockService>(control_interface(),
2626 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002627 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002628 manager()));
2629 manager()->RegisterService(mock_service);
2630 EXPECT_FALSE(mock_service->favorite());
2631 EXPECT_FALSE(mock_service->auto_connect());
2632
Gaurav Shah435de2c2011-11-17 19:01:07 -08002633 EXPECT_CALL(*mock_service.get(), IsConnected())
2634 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002635 manager()->UpdateService(mock_service);
2636 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2637 // to mock out MakeFavorite. And mocking that out would break the
2638 // SortServices test. (crosbug.com/23370)
2639 EXPECT_TRUE(mock_service->favorite());
2640 EXPECT_TRUE(mock_service->auto_connect());
2641}
2642
Thieu Led4e9e552012-02-16 16:26:07 -08002643TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2644 // This tests the case where the user connects to a service that is
2645 // currently associated with a profile. We want to make sure that the
2646 // favorite flag is set and that the flag is saved to the current
2647 // profile.
2648 scoped_refptr<MockService> mock_service(
2649 new NiceMock<MockService>(control_interface(),
2650 dispatcher(),
2651 metrics(),
2652 manager()));
2653 manager()->RegisterService(mock_service);
2654 EXPECT_FALSE(mock_service->favorite());
2655 EXPECT_FALSE(mock_service->auto_connect());
2656
Gary Moraind93615e2012-04-27 11:50:03 -07002657 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002658 new MockProfile(
2659 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002660
Gary Moraind93615e2012-04-27 11:50:03 -07002661 mock_service->set_profile(profile);
2662 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002663 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002664 EXPECT_CALL(*profile,
2665 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002666 manager()->UpdateService(mock_service);
2667 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2668 // to mock out MakeFavorite. And mocking that out would break the
2669 // SortServices test. (crosbug.com/23370)
2670 EXPECT_TRUE(mock_service->favorite());
2671 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002672 // This releases the ref on the mock profile.
2673 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002674}
2675
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002676TEST_F(ManagerTest, SaveSuccessfulService) {
2677 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002678 new StrictMock<MockProfile>(
2679 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002680 AdoptProfile(manager(), profile);
2681 scoped_refptr<MockService> service(
2682 new NiceMock<MockService>(control_interface(),
2683 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002684 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002685 manager()));
2686
2687 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2688 ServiceRefPtr expect_service(service.get());
2689
2690 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2691 .WillOnce(Return(false));
2692 manager()->RegisterService(service);
2693
2694 EXPECT_CALL(*service.get(), state())
2695 .WillRepeatedly(Return(Service::kStateConnected));
2696 EXPECT_CALL(*service.get(), IsConnected())
2697 .WillRepeatedly(Return(true));
2698 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2699 .WillOnce(Return(true));
2700 manager()->UpdateService(service);
2701}
2702
Darin Petkove7c6ad32012-06-29 10:22:09 +02002703TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002704 MockProfile *profile0 =
2705 new MockProfile(control_interface(), metrics(), manager(), "");
2706 MockProfile *profile1 =
2707 new MockProfile(control_interface(), metrics(), manager(), "");
2708 MockProfile *profile2 =
2709 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002710 AdoptProfile(manager(), profile0); // Passes ownership.
2711 AdoptProfile(manager(), profile1); // Passes ownership.
2712 AdoptProfile(manager(), profile2); // Passes ownership.
2713 DeviceRefPtr device_ref(mock_devices_[0].get());
2714 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2715 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2716 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2717 manager()->UpdateDevice(mock_devices_[0]);
2718}
2719
Paul Stewart1b253142012-01-26 14:05:52 -08002720TEST_F(ManagerTest, EnumerateProfiles) {
2721 vector<string> profile_paths;
2722 for (size_t i = 0; i < 10; i++) {
2723 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002724 new StrictMock<MockProfile>(
2725 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002726 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002727 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2728 .WillOnce(Return(profile_paths.back()));
2729 AdoptProfile(manager(), profile);
2730 }
2731
2732 Error error;
2733 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2734 EXPECT_TRUE(error.IsSuccess());
2735 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2736 for (size_t i = 0; i < profile_paths.size(); i++) {
2737 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2738 }
2739}
2740
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002741TEST_F(ManagerTest, AutoConnectOnRegister) {
2742 MockServiceRefPtr service = MakeAutoConnectableService();
2743 EXPECT_CALL(*service.get(), AutoConnect());
2744 manager()->RegisterService(service);
2745 dispatcher()->DispatchPendingEvents();
2746}
2747
2748TEST_F(ManagerTest, AutoConnectOnUpdate) {
2749 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002750 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002751 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002752 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002753 manager()->RegisterService(service1);
2754 manager()->RegisterService(service2);
2755 dispatcher()->DispatchPendingEvents();
2756
2757 EXPECT_CALL(*service1.get(), AutoConnect());
2758 EXPECT_CALL(*service2.get(), state())
2759 .WillRepeatedly(Return(Service::kStateFailure));
2760 EXPECT_CALL(*service2.get(), IsFailed())
2761 .WillRepeatedly(Return(true));
2762 EXPECT_CALL(*service2.get(), IsConnected())
2763 .WillRepeatedly(Return(false));
2764 manager()->UpdateService(service2);
2765 dispatcher()->DispatchPendingEvents();
2766}
2767
2768TEST_F(ManagerTest, AutoConnectOnDeregister) {
2769 MockServiceRefPtr service1 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002770 service1->SetPriority(1, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002771 MockServiceRefPtr service2 = MakeAutoConnectableService();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002772 service2->SetPriority(2, NULL);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002773 manager()->RegisterService(service1);
2774 manager()->RegisterService(service2);
2775 dispatcher()->DispatchPendingEvents();
2776
2777 EXPECT_CALL(*service1.get(), AutoConnect());
2778 manager()->DeregisterService(service2);
2779 dispatcher()->DispatchPendingEvents();
2780}
2781
Darin Petkov3ec55342012-09-28 14:04:44 +02002782TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2783 MockServiceRefPtr service = MakeAutoConnectableService();
2784 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2785 SetPowerManager();
2786 EXPECT_CALL(*service, AutoConnect()).Times(0);
2787 manager()->RegisterService(service);
2788 dispatcher()->DispatchPendingEvents();
2789}
2790
Darin Petkovca621542012-07-25 14:25:56 +02002791TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2792 MockServiceRefPtr service = MakeAutoConnectableService();
2793 SetPowerState(PowerManagerProxyDelegate::kMem);
2794 SetPowerManager();
2795 EXPECT_CALL(*service, AutoConnect()).Times(0);
2796 manager()->RegisterService(service);
2797 dispatcher()->DispatchPendingEvents();
2798}
2799
2800TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2801 MockServiceRefPtr service = MakeAutoConnectableService();
2802 SetPowerState(PowerManagerProxyDelegate::kOn);
2803 SetPowerManager();
2804 EXPECT_CALL(*service, AutoConnect());
2805 manager()->RegisterService(service);
2806 dispatcher()->DispatchPendingEvents();
2807}
2808
2809TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2810 MockServiceRefPtr service = MakeAutoConnectableService();
2811 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2812 SetPowerManager();
2813 EXPECT_CALL(*service, AutoConnect());
2814 manager()->RegisterService(service);
2815 dispatcher()->DispatchPendingEvents();
2816}
2817
Paul Stewart63864b62012-11-07 15:10:55 -08002818TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2819 SetRunning(false);
2820 MockServiceRefPtr service = MakeAutoConnectableService();
2821 EXPECT_CALL(*service, AutoConnect()).Times(0);
2822 manager()->RegisterService(service);
2823 dispatcher()->DispatchPendingEvents();
2824}
2825
Darin Petkovca621542012-07-25 14:25:56 +02002826TEST_F(ManagerTest, OnPowerStateChanged) {
2827 MockServiceRefPtr service = MakeAutoConnectableService();
2828 SetPowerState(PowerManagerProxyDelegate::kOn);
2829 SetPowerManager();
2830 EXPECT_CALL(*service, AutoConnect());
2831 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002832 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002833 dispatcher()->DispatchPendingEvents();
2834
mukesh agrawal784566d2012-08-08 18:32:58 -07002835 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002836 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2837 EXPECT_CALL(*service, AutoConnect());
2838 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002839 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002840
mukesh agrawal784566d2012-08-08 18:32:58 -07002841 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002842 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2843 EXPECT_CALL(*service, AutoConnect()).Times(0);
2844 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002845 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002846}
2847
Darin Petkov3ec55342012-09-28 14:04:44 +02002848TEST_F(ManagerTest, AddTerminationAction) {
2849 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002850 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002851 SetPowerManager();
2852 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2853 manager()->AddTerminationAction("action1", base::Closure());
2854 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2855 manager()->AddTerminationAction("action2", base::Closure());
2856}
2857
2858TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002859 const char kKey1[] = "action1";
2860 const char kKey2[] = "action2";
2861 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002862
2863 MockPowerManager &power_manager = *power_manager_;
2864 SetPowerManager();
2865
2866 // Removing an action when the hook table is empty should not result in any
2867 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002868 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002869 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2870 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2871 manager()->RemoveTerminationAction("unknown");
2872 Mock::VerifyAndClearExpectations(&power_manager);
2873
Daniel Eratf9753672013-01-24 10:17:02 -08002874 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2875 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002876 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002877 manager()->AddTerminationAction(kKey1, base::Closure());
2878 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2879 manager()->AddTerminationAction(kKey2, base::Closure());
2880
2881 // Removing an action that ends up with a non-empty hook table should not
2882 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002883 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002884 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2885 manager()->RemoveTerminationAction(kKey1);
2886 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2887 Mock::VerifyAndClearExpectations(&power_manager);
2888
2889 // Removing the last action should trigger unregistering from the power
2890 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002891 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2892 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002893 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2894 manager()->RemoveTerminationAction(kKey2);
2895 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2896}
2897
2898TEST_F(ManagerTest, RunTerminationActions) {
2899 TerminationActionTest test_action;
2900 const string kActionName = "action";
2901
2902 EXPECT_CALL(test_action, Done(_));
2903 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2904 test_action.AsWeakPtr()));
2905
2906 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2907 Bind(&TerminationActionTest::Action,
2908 test_action.AsWeakPtr()));
2909 test_action.set_manager(manager());
2910 EXPECT_CALL(test_action, Done(_));
2911 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2912 test_action.AsWeakPtr()));
2913}
2914
Daniel Erat0818cca2012-12-14 10:16:21 -08002915TEST_F(ManagerTest, OnSuspendImminent) {
2916 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002917 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08002918 EXPECT_CALL(*power_manager_,
2919 ReportSuspendReadiness(
2920 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002921 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002922 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02002923}
2924
2925TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002926 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02002927 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08002928 EXPECT_CALL(*power_manager_,
2929 ReportSuspendReadiness(
2930 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002931 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002932 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02002933}
2934
Paul Stewartc681fa02012-03-02 19:40:04 -08002935TEST_F(ManagerTest, RecheckPortal) {
2936 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
2937 .WillOnce(Return(false));
2938 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
2939 .WillOnce(Return(true));
2940 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
2941 .Times(0);
2942
2943 manager()->RegisterDevice(mock_devices_[0]);
2944 manager()->RegisterDevice(mock_devices_[1]);
2945 manager()->RegisterDevice(mock_devices_[2]);
2946
2947 manager()->RecheckPortal(NULL);
2948}
2949
Paul Stewartd215af62012-04-24 23:25:50 -07002950TEST_F(ManagerTest, RecheckPortalOnService) {
2951 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
2952 dispatcher(),
2953 metrics(),
2954 manager());
2955 EXPECT_CALL(*mock_devices_[0].get(),
2956 IsConnectedToService(IsRefPtrTo(service)))
2957 .WillOnce(Return(false));
2958 EXPECT_CALL(*mock_devices_[1].get(),
2959 IsConnectedToService(IsRefPtrTo(service)))
2960 .WillOnce(Return(true));
2961 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
2962 .WillOnce(Return(true));
2963 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
2964 .Times(0);
2965
2966 manager()->RegisterDevice(mock_devices_[0]);
2967 manager()->RegisterDevice(mock_devices_[1]);
2968 manager()->RegisterDevice(mock_devices_[2]);
2969
2970 manager()->RecheckPortalOnService(service);
2971}
2972
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002973TEST_F(ManagerTest, GetDefaultService) {
2974 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002975 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002976
2977 scoped_refptr<MockService> mock_service(
2978 new NiceMock<MockService>(control_interface(),
2979 dispatcher(),
2980 metrics(),
2981 manager()));
2982
2983 manager()->RegisterService(mock_service);
2984 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002985 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002986
2987 scoped_refptr<MockConnection> mock_connection(
2988 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002989 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002990 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002991 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002992
Paul Stewartce4ec192012-03-14 12:53:46 -07002993 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002994 manager()->DeregisterService(mock_service);
2995}
2996
Paul Stewart13ed2252012-03-21 12:52:46 -07002997TEST_F(ManagerTest, GetServiceWithGUID) {
2998 scoped_refptr<MockService> mock_service0(
2999 new NiceMock<MockService>(control_interface(),
3000 dispatcher(),
3001 metrics(),
3002 manager()));
3003
3004 scoped_refptr<MockService> mock_service1(
3005 new NiceMock<MockService>(control_interface(),
3006 dispatcher(),
3007 metrics(),
3008 manager()));
3009
Paul Stewartcb59fed2012-03-21 21:14:46 -07003010 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
3011 .Times(0);
3012 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
3013 .Times(0);
3014
Paul Stewart13ed2252012-03-21 12:52:46 -07003015 manager()->RegisterService(mock_service0);
3016 manager()->RegisterService(mock_service1);
3017
3018 const string kGUID0 = "GUID0";
3019 const string kGUID1 = "GUID1";
3020
3021 {
3022 Error error;
3023 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3024 EXPECT_FALSE(error.IsSuccess());
3025 EXPECT_FALSE(service);
3026 }
3027
3028 KeyValueStore args;
3029 args.SetString(flimflam::kGuidProperty, kGUID1);
3030
3031 {
3032 Error error;
3033 ServiceRefPtr service = manager()->GetService(args, &error);
3034 EXPECT_EQ(Error::kInvalidArguments, error.type());
3035 EXPECT_FALSE(service);
3036 }
3037
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003038 mock_service0->SetGuid(kGUID0, NULL);
3039 mock_service1->SetGuid(kGUID1, NULL);
Paul Stewart13ed2252012-03-21 12:52:46 -07003040
3041 {
3042 Error error;
3043 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3044 EXPECT_TRUE(error.IsSuccess());
3045 EXPECT_EQ(mock_service0.get(), service.get());
3046 }
3047
3048 {
3049 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003050 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3051 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003052 ServiceRefPtr service = manager()->GetService(args, &error);
3053 EXPECT_TRUE(error.IsSuccess());
3054 EXPECT_EQ(mock_service1.get(), service.get());
3055 }
3056
3057 manager()->DeregisterService(mock_service0);
3058 manager()->DeregisterService(mock_service1);
3059}
3060
Gary Morain028545d2012-04-07 14:55:52 -07003061
3062TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003063 EXPECT_FALSE(manager()->IsOnline());
3064 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3065
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003066 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003067 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003068 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3069 .Times(AnyNumber());
3070 scoped_refptr<MockService> mock_service0(
3071 new NiceMock<MockService>(control_interface(),
3072 dispatcher(),
3073 metrics(),
3074 manager()));
3075
3076 scoped_refptr<MockService> mock_service1(
3077 new NiceMock<MockService>(control_interface(),
3078 dispatcher(),
3079 metrics(),
3080 manager()));
3081
3082 EXPECT_CALL(*mock_service0.get(), IsConnected())
3083 .WillRepeatedly(Return(false));
3084 EXPECT_CALL(*mock_service1.get(), IsConnected())
3085 .WillRepeatedly(Return(false));
3086
3087 manager()->RegisterService(mock_service0);
3088 manager()->RegisterService(mock_service1);
3089
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003090 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003091 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3092
3093 manager()->DeregisterService(mock_service0);
3094 manager()->DeregisterService(mock_service1);
3095}
3096
3097TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003098 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003099 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003100 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3101 .Times(AnyNumber());
3102 scoped_refptr<MockService> mock_service0(
3103 new NiceMock<MockService>(control_interface(),
3104 dispatcher(),
3105 metrics(),
3106 manager()));
3107
3108 scoped_refptr<MockService> mock_service1(
3109 new NiceMock<MockService>(control_interface(),
3110 dispatcher(),
3111 metrics(),
3112 manager()));
3113
3114 EXPECT_CALL(*mock_service0.get(), IsConnected())
3115 .WillRepeatedly(Return(false));
3116 EXPECT_CALL(*mock_service1.get(), IsConnected())
3117 .WillRepeatedly(Return(true));
3118 EXPECT_CALL(*mock_service0.get(), state())
3119 .WillRepeatedly(Return(Service::kStateIdle));
3120 EXPECT_CALL(*mock_service1.get(), state())
3121 .WillRepeatedly(Return(Service::kStateConnected));
3122
3123 manager()->RegisterService(mock_service0);
3124 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003125 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003126
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003127 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003128 EXPECT_EQ("online", manager()->CalculateState(NULL));
3129
3130 manager()->DeregisterService(mock_service0);
3131 manager()->DeregisterService(mock_service1);
3132}
3133
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003134TEST_F(ManagerTest, StartupPortalList) {
3135 // Simulate loading value from the default profile.
3136 const string kProfileValue("wifi,vpn");
3137 manager()->props_.check_portal_list = kProfileValue;
3138
3139 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3140 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3141 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3142
3143 const string kStartupValue("cellular,ethernet");
3144 manager()->SetStartupPortalList(kStartupValue);
3145 // Ensure profile value is not overwritten, so when we save the default
3146 // profile, the correct value will still be written.
3147 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3148
3149 // However we should read back a different list.
3150 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3151 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3152 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3153
3154 const string kRuntimeValue("ppp");
3155 // Setting a runtime value over the control API should overwrite both
3156 // the profile value and what we read back.
3157 Error error;
3158 manager()->mutable_store()->SetStringProperty(
3159 flimflam::kCheckPortalListProperty,
3160 kRuntimeValue,
3161 &error);
3162 ASSERT_TRUE(error.IsSuccess());
3163 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3164 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3165 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3166 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3167}
3168
Paul Stewart036dba02012-08-07 12:34:41 -07003169TEST_F(ManagerTest, LinkMonitorEnabled) {
3170 const string kEnabledTechnologies("wifi,vpn");
3171 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3172 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3173 EXPECT_FALSE(
3174 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3175}
3176
Paul Stewart85aea152013-01-22 09:31:56 -08003177TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003178 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003179 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003180 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003181 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003182 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003183 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3184 AdoptProfile(manager(), profile);
3185 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3186 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3187 scoped_ptr<MockStore> store1(new MockStore);
3188 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3189}
3190
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003191TEST_F(ManagerTest, EnableTechnology) {
3192 Error error(Error::kOperationInitiated);
3193 ResultCallback callback;
3194 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3195 EXPECT_TRUE(error.IsSuccess());
3196
Joshua Krollda798622012-06-05 12:30:48 -07003197 ON_CALL(*mock_devices_[0], technology())
3198 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003199
3200 manager()->RegisterDevice(mock_devices_[0]);
3201
3202 // Device is enabled, so expect operation is successful.
3203 mock_devices_[0]->enabled_ = true;
3204 error.Populate(Error::kOperationInitiated);
3205 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3206 EXPECT_TRUE(error.IsSuccess());
3207
3208 // Device is disabled, so expect operation in progress.
3209 mock_devices_[0]->enabled_ = false;
3210 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3211 error.Populate(Error::kOperationInitiated);
3212 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3213 EXPECT_TRUE(error.IsOngoing());
3214}
3215
3216TEST_F(ManagerTest, DisableTechnology) {
3217 Error error(Error::kOperationInitiated);
3218 ResultCallback callback;
3219 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3220 EXPECT_TRUE(error.IsSuccess());
3221
Joshua Krollda798622012-06-05 12:30:48 -07003222 ON_CALL(*mock_devices_[0], technology())
3223 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003224
3225 manager()->RegisterDevice(mock_devices_[0]);
3226
3227 // Device is disabled, so expect operation is successful.
3228 error.Populate(Error::kOperationInitiated);
3229 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3230 EXPECT_TRUE(error.IsSuccess());
3231
3232 // Device is enabled, so expect operation in progress.
3233 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3234 mock_devices_[0]->enabled_ = true;
3235 error.Populate(Error::kOperationInitiated);
3236 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3237 EXPECT_TRUE(error.IsOngoing());
3238}
3239
Paul Stewart4d5efb72012-09-17 12:24:34 -07003240TEST_F(ManagerTest, IgnoredSearchList) {
3241 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
3242 SetResolver(resolver.get());
3243 vector<string> ignored_paths;
3244 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3245 SetIgnoredDNSSearchPaths("");
3246 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3247
3248 const string kIgnored0 = "chromium.org";
3249 ignored_paths.push_back(kIgnored0);
3250 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3251 SetIgnoredDNSSearchPaths(kIgnored0);
3252 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3253
3254 const string kIgnored1 = "google.com";
3255 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3256 ignored_paths.push_back(kIgnored1);
3257 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3258 SetIgnoredDNSSearchPaths(kIgnoredSum);
3259 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3260
3261 SetResolver(Resolver::GetInstance());
3262}
3263
Paul Stewartbfb82552012-10-24 16:48:48 -07003264TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3265 // Test to make sure that every service state-change causes the
3266 // Manager to emit a new service list.
3267 scoped_refptr<MockService> mock_service(
3268 new NiceMock<MockService>(control_interface(),
3269 dispatcher(),
3270 metrics(),
3271 manager()));
3272 EXPECT_CALL(*mock_service, state())
3273 .WillRepeatedly(Return(Service::kStateIdle));
3274
3275 manager()->RegisterService(mock_service);
3276 EXPECT_CALL(
3277 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3278 flimflam::kServicesProperty, _)).Times(1);
3279 EXPECT_CALL(
3280 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3281 flimflam::kServiceWatchListProperty, _)).Times(1);
3282 CompleteServiceSort();
3283
3284 Mock::VerifyAndClearExpectations(manager_adaptor_);
3285 EXPECT_CALL(
3286 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3287 flimflam::kServicesProperty, _)).Times(1);
3288 EXPECT_CALL(
3289 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3290 flimflam::kServiceWatchListProperty, _)).Times(1);
3291 manager()->UpdateService(mock_service.get());
3292 CompleteServiceSort();
3293
3294 manager()->DeregisterService(mock_service);
3295}
3296
3297TEST_F(ManagerTest, EnumerateServices) {
3298 scoped_refptr<MockService> mock_service(
3299 new NiceMock<MockService>(control_interface(),
3300 dispatcher(),
3301 metrics(),
3302 manager()));
3303 manager()->RegisterService(mock_service);
3304
3305 EXPECT_CALL(*mock_service, state())
3306 .WillRepeatedly(Return(Service::kStateConnected));
3307 EXPECT_CALL(*mock_service, IsVisible())
3308 .WillRepeatedly(Return(false));
3309 EXPECT_TRUE(EnumerateAvailableServices().empty());
3310 EXPECT_TRUE(EnumerateWatchedServices().empty());
3311
3312 EXPECT_CALL(*mock_service, state())
3313 .WillRepeatedly(Return(Service::kStateIdle));
3314 EXPECT_TRUE(EnumerateAvailableServices().empty());
3315 EXPECT_TRUE(EnumerateWatchedServices().empty());
3316
3317 EXPECT_CALL(*mock_service, IsVisible())
3318 .WillRepeatedly(Return(true));
3319 Service::ConnectState unwatched_states[] = {
3320 Service::kStateUnknown,
3321 Service::kStateIdle,
3322 Service::kStateFailure
3323 };
3324 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3325 EXPECT_CALL(*mock_service, state())
3326 .WillRepeatedly(Return(unwatched_states[i]));
3327 EXPECT_FALSE(EnumerateAvailableServices().empty());
3328 EXPECT_TRUE(EnumerateWatchedServices().empty());
3329 }
3330
3331 Service::ConnectState watched_states[] = {
3332 Service::kStateAssociating,
3333 Service::kStateConfiguring,
3334 Service::kStateConnected,
3335 Service::kStateDisconnected,
3336 Service::kStatePortal,
3337 Service::kStateOnline
3338 };
3339 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3340 EXPECT_CALL(*mock_service, state())
3341 .WillRepeatedly(Return(watched_states[i]));
3342 EXPECT_FALSE(EnumerateAvailableServices().empty());
3343 EXPECT_FALSE(EnumerateWatchedServices().empty());
3344 }
3345
3346 manager()->DeregisterService(mock_service);
3347}
3348
Paul Stewart39db5ca2013-03-18 14:15:17 -07003349TEST_F(ManagerTest, ConnectToBestServices) {
3350 scoped_refptr<MockService> wifi_service0(
3351 new NiceMock<MockService>(control_interface(),
3352 dispatcher(),
3353 metrics(),
3354 manager()));
3355 EXPECT_CALL(*wifi_service0.get(), state())
3356 .WillRepeatedly(Return(Service::kStateIdle));
3357 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3358 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003359 wifi_service0->SetConnectable(true);
3360 wifi_service0->SetAutoConnect(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003361 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3362 EXPECT_CALL(*wifi_service0.get(), technology())
3363 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003364 EXPECT_CALL(*wifi_service0.get(), IsVisible())
3365 .WillRepeatedly(Return(false));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003366
3367 scoped_refptr<MockService> wifi_service1(
3368 new NiceMock<MockService>(control_interface(),
3369 dispatcher(),
3370 metrics(),
3371 manager()));
3372 EXPECT_CALL(*wifi_service1.get(), state())
3373 .WillRepeatedly(Return(Service::kStateIdle));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003374 EXPECT_CALL(*wifi_service1.get(), IsVisible())
3375 .WillRepeatedly(Return(true));
Paul Stewart39db5ca2013-03-18 14:15:17 -07003376 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3377 .WillRepeatedly(Return(false));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003378 wifi_service1->SetAutoConnect(true);
3379 wifi_service1->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003380 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3381 EXPECT_CALL(*wifi_service1.get(), technology())
3382 .WillRepeatedly(Return(Technology::kWifi));
3383
3384 scoped_refptr<MockService> wifi_service2(
3385 new NiceMock<MockService>(control_interface(),
3386 dispatcher(),
3387 metrics(),
3388 manager()));
3389 EXPECT_CALL(*wifi_service2.get(), state())
3390 .WillRepeatedly(Return(Service::kStateConnected));
3391 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3392 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003393 EXPECT_CALL(*wifi_service2.get(), IsVisible())
3394 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003395 wifi_service2->SetAutoConnect(true);
3396 wifi_service2->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003397 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3398 EXPECT_CALL(*wifi_service2.get(), technology())
3399 .WillRepeatedly(Return(Technology::kWifi));
3400
3401 manager()->RegisterService(wifi_service0);
3402 manager()->RegisterService(wifi_service1);
3403 manager()->RegisterService(wifi_service2);
3404
3405 CompleteServiceSort();
3406 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3407
3408 scoped_refptr<MockService> cell_service(
3409 new NiceMock<MockService>(control_interface(),
3410 dispatcher(),
3411 metrics(),
3412 manager()));
3413
3414 EXPECT_CALL(*cell_service.get(), state())
3415 .WillRepeatedly(Return(Service::kStateConnected));
3416 EXPECT_CALL(*cell_service.get(), IsConnected())
3417 .WillRepeatedly(Return(true));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003418 EXPECT_CALL(*cell_service.get(), IsVisible())
3419 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003420 wifi_service2->SetAutoConnect(true);
3421 cell_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003422 EXPECT_CALL(*cell_service.get(), technology())
3423 .WillRepeatedly(Return(Technology::kCellular));
3424 manager()->RegisterService(cell_service);
3425
3426 scoped_refptr<MockService> vpn_service(
3427 new NiceMock<MockService>(control_interface(),
3428 dispatcher(),
3429 metrics(),
3430 manager()));
3431
3432 EXPECT_CALL(*vpn_service.get(), state())
3433 .WillRepeatedly(Return(Service::kStateIdle));
3434 EXPECT_CALL(*vpn_service.get(), IsConnected())
3435 .WillRepeatedly(Return(false));
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003436 EXPECT_CALL(*vpn_service.get(), IsVisible())
3437 .WillRepeatedly(Return(true));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07003438 wifi_service2->SetAutoConnect(false);
3439 vpn_service->SetConnectable(true);
Paul Stewart39db5ca2013-03-18 14:15:17 -07003440 EXPECT_CALL(*vpn_service.get(), technology())
3441 .WillRepeatedly(Return(Technology::kVPN));
3442 manager()->RegisterService(vpn_service);
3443
3444 // The connected services should be at the top.
3445 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3446
Paul Stewartf7d7d3f2013-04-24 14:47:44 -07003447 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(0); // Not visible.
3448 EXPECT_CALL(*wifi_service1.get(), Connect(_, _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003449 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
3450 EXPECT_CALL(*cell_service.get(), Connect(_, _)).Times(0); // Is connected.
3451 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003452
3453 manager()->ConnectToBestServices(NULL);
3454 dispatcher()->DispatchPendingEvents();
3455
3456 // After this operation, since the Connect calls above are mocked and
3457 // no actual state changes have occurred, we should expect that the
3458 // service sorting order will not have changed.
3459 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3460}
3461
Christopher Wiley1057cd72013-02-28 15:21:29 -08003462TEST_F(ManagerTest, VerifyDestination) {
3463 const string kFakeCertificate("fake cert");
3464 const string kFakePublicKey("fake public key");
3465 const string kFakeNonce("fake public key");
3466 const string kFakeSignedData("fake signed data");
3467 const string kFakeUdn("fake udn");
3468 const char kSSIDStr[] = "fake ssid";
3469 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
3470 const string kFakeData("muffin man");
3471 scoped_refptr<MockWiFiService> mock_destination(
3472 new NiceMock<MockWiFiService>(control_interface(),
3473 dispatcher(),
3474 metrics(),
3475 manager(),
3476 wifi_provider_,
3477 kSSID,
3478 "",
3479 "none",
3480 false));
3481 manager()->RegisterService(mock_destination);
3482 StrictMock<DestinationVerificationTest> dv_test;
3483
3484 // Verify that if we're not connected to anything, verification fails.
3485 {
3486 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3487 kFakePublicKey,
3488 kFakeNonce,
3489 kFakeSignedData,
3490 kFakeUdn,
3491 kSSID,
3492 _,
3493 _,
3494 _))
3495 .Times(0);
3496 Error error(Error::kOperationInitiated);
3497 ResultBoolCallback cb = Bind(
3498 &DestinationVerificationTest::ResultBoolCallbackStub,
3499 dv_test.AsWeakPtr());
3500 manager()->VerifyDestination(kFakeCertificate,
3501 kFakePublicKey,
3502 kFakeNonce,
3503 kFakeSignedData,
3504 kFakeUdn,
3505 cb,
3506 &error);
3507 EXPECT_TRUE(error.IsFailure());
3508 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3509 }
3510
3511 // Making the service look online will let service lookup in
3512 // VerifyDestinatoin succeed.
3513 EXPECT_CALL(*mock_destination.get(), IsConnected())
3514 .WillRepeatedly(Return(true));
3515
3516 // Lead off by verifying that the basic VerifyDestination flow works.
3517 {
3518 ResultBoolCallback passed_down_callback;
3519 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3520 kFakePublicKey,
3521 kFakeNonce,
3522 kFakeSignedData,
3523 kFakeUdn,
3524 kSSID,
3525 _,
3526 _,
3527 _))
3528 .Times(1)
3529 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3530 // Ask the manager to verify the current destination. This should look
3531 // up our previously registered service, and pass some metadata about
3532 // that service down to the CryptoUtilProxy to verify.
3533 Error error(Error::kOperationInitiated);
3534 ResultBoolCallback cb = Bind(
3535 &DestinationVerificationTest::ResultBoolCallbackStub,
3536 dv_test.AsWeakPtr());
3537 manager()->VerifyDestination(kFakeCertificate,
3538 kFakePublicKey,
3539 kFakeNonce,
3540 kFakeSignedData,
3541 kFakeUdn,
3542 cb,
3543 &error);
3544 // We assert here, because if the operation is not ongoing, it is
3545 // inconsistent with shim behavior to call the callback anyway.
3546 ASSERT_TRUE(error.IsOngoing());
3547 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3548 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3549 // Call the callback passed into the CryptoUtilProxy, which
3550 // should find its way into the callback passed into the manager.
3551 // In real code, that callback passed into the manager is from the
3552 // DBus adaptor.
3553 Error e;
3554 passed_down_callback.Run(e, true);
3555 Mock::VerifyAndClearExpectations(&dv_test);
3556 }
3557
3558 // Now for a slightly more complex variant. When we encrypt data,
3559 // we do the same verification step but monkey with the callback to
3560 // link ourselves to an encrypt step afterward.
3561 {
3562 ResultBoolCallback passed_down_callback;
3563 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3564 kFakePublicKey,
3565 kFakeNonce,
3566 kFakeSignedData,
3567 kFakeUdn,
3568 kSSID,
3569 _,
3570 _,
3571 _))
3572 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3573
3574 Error error(Error::kOperationInitiated);
3575 ResultStringCallback cb = Bind(
3576 &DestinationVerificationTest::ResultStringCallbackStub,
3577 dv_test.AsWeakPtr());
3578 manager()->VerifyAndEncryptData(kFakeCertificate,
3579 kFakePublicKey,
3580 kFakeNonce,
3581 kFakeSignedData,
3582 kFakeUdn,
3583 kFakeData,
3584 cb,
3585 &error);
3586 ASSERT_TRUE(error.IsOngoing());
3587 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3588 // Now, if we call that passed down callback, we should see encrypt being
3589 // called.
3590 ResultStringCallback second_passed_down_callback;
3591 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3592 kFakeData,
3593 _,
3594 _))
3595 .Times(1)
3596 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3597 Return(true)));
3598 Error e;
3599 passed_down_callback.Run(e, true);
3600 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3601 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3602 // And if we call the second passed down callback, we should see the
3603 // original function we passed down to VerifyDestination getting called.
3604 e.Reset();
3605 second_passed_down_callback.Run(e, "");
3606 Mock::VerifyAndClearExpectations(&dv_test);
3607 }
3608
3609 // If verification fails on the way to trying to encrypt, we should ditch
3610 // without calling encrypt at all.
3611 {
3612 ResultBoolCallback passed_down_callback;
3613 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3614 kFakePublicKey,
3615 kFakeNonce,
3616 kFakeSignedData,
3617 kFakeUdn,
3618 kSSID,
3619 _,
3620 _,
3621 _))
3622 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3623
3624 Error error(Error::kOperationInitiated);
3625 ResultStringCallback cb = Bind(
3626 &DestinationVerificationTest::ResultStringCallbackStub,
3627 dv_test.AsWeakPtr());
3628 manager()->VerifyAndEncryptData(kFakeCertificate,
3629 kFakePublicKey,
3630 kFakeNonce,
3631 kFakeSignedData,
3632 kFakeUdn,
3633 kFakeData,
3634 cb,
3635 &error);
3636 ASSERT_TRUE(error.IsOngoing());
3637 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3638 Error e(Error::kOperationFailed);
3639 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3640 // Although we're ditching, this callback is what cleans up the pending
3641 // DBus call.
3642 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3643 passed_down_callback.Run(e, false);
3644 Mock::VerifyAndClearExpectations(&dv_test);
3645 }
3646}
3647
Paul Stewartd2e1c362013-03-03 19:06:07 -08003648TEST_F(ManagerTest, IsProfileBefore) {
3649 scoped_refptr<MockProfile> profile0(
3650 new NiceMock<MockProfile>(
3651 control_interface(), metrics(), manager(), ""));
3652 scoped_refptr<MockProfile> profile1(
3653 new NiceMock<MockProfile>(
3654 control_interface(), metrics(), manager(), ""));
3655
3656 AdoptProfile(manager(), profile0);
3657 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3658 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3659 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3660
3661 // A few abnormal cases, but it's good to track their behavior.
3662 scoped_refptr<MockProfile> profile2(
3663 new NiceMock<MockProfile>(
3664 control_interface(), metrics(), manager(), ""));
3665 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3666 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3667 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3668 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3669}
3670
Paul Stewart967eaeb2013-04-25 19:53:07 -07003671TEST_F(ManagerTest, GetLoadableProfileEntriesForService) {
3672 MockStore storage0;
3673 MockStore storage1;
3674 MockStore storage2;
3675
3676 scoped_refptr<MockProfile> profile0(
3677 new NiceMock<MockProfile>(
3678 control_interface(), metrics(), manager(), ""));
3679 scoped_refptr<MockProfile> profile1(
3680 new NiceMock<MockProfile>(
3681 control_interface(), metrics(), manager(), ""));
3682 scoped_refptr<MockProfile> profile2(
3683 new NiceMock<MockProfile>(
3684 control_interface(), metrics(), manager(), ""));
3685
3686 AdoptProfile(manager(), profile0);
3687 AdoptProfile(manager(), profile1);
3688 AdoptProfile(manager(), profile2);
3689
3690 scoped_refptr<MockService> service(
3691 new NiceMock<MockService>(control_interface(),
3692 dispatcher(),
3693 metrics(),
3694 manager()));
3695
3696 EXPECT_CALL(*profile0, GetConstStorage()).WillOnce(Return(&storage0));
3697 EXPECT_CALL(*profile1, GetConstStorage()).WillOnce(Return(&storage1));
3698 EXPECT_CALL(*profile2, GetConstStorage()).WillOnce(Return(&storage2));
3699
3700 const string kEntry0("aluminum_crutch");
3701 const string kEntry2("rehashed_faces");
3702
3703 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage0)))
3704 .WillOnce(Return(kEntry0));
3705 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage1)))
3706 .WillOnce(Return(""));
3707 EXPECT_CALL(*service, GetLoadableStorageIdentifier(Ref(storage2)))
3708 .WillOnce(Return(kEntry2));
3709
3710 const string kProfileRpc0("service_station");
3711 const string kProfileRpc2("crystal_tiaras");
3712
3713 EXPECT_CALL(*profile0, GetRpcIdentifier()).WillOnce(Return(kProfileRpc0));
3714 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(0);
3715 EXPECT_CALL(*profile2, GetRpcIdentifier()).WillOnce(Return(kProfileRpc2));
3716
3717 map<string, string> entries =
3718 manager()->GetLoadableProfileEntriesForService(service);
3719 EXPECT_EQ(2, entries.size());
3720 EXPECT_TRUE(ContainsKey(entries, kProfileRpc0));
3721 EXPECT_TRUE(ContainsKey(entries, kProfileRpc2));
3722 EXPECT_EQ(kEntry0, entries[kProfileRpc0]);
3723 EXPECT_EQ(kEntry2, entries[kProfileRpc2]);
3724}
3725
Chris Masone9be4a9d2011-05-16 15:44:09 -07003726} // namespace shill