blob: c75735a37fc773f5d2e95104f9fbccd73aab8da1 [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"
Chris Masone7aa5f902011-07-11 11:13:35 -070033#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000034#include "shill/mock_metrics.h"
Darin Petkovca621542012-07-25 14:25:56 +020035#include "shill/mock_power_manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070036#include "shill/mock_profile.h"
Paul Stewart4d5efb72012-09-17 12:24:34 -070037#include "shill/mock_resolver.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070038#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070039#include "shill/mock_store.h"
Paul Stewart3c504012013-01-17 17:49:58 -080040#include "shill/mock_wifi_provider.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070041#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042#include "shill/property_store_unittest.h"
Darin Petkovca621542012-07-25 14:25:56 +020043#include "shill/proxy_factory.h"
Chris Masone6515aab2011-10-12 16:19:09 -070044#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070045#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020046#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070047
Christopher Wiley1057cd72013-02-28 15:21:29 -080048using base::Bind;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080049using base::FilePath;
Paul Stewart5ad16062013-02-21 18:10:48 -080050using base::ScopedTempDir;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070051using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070052using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070053using std::string;
54using std::vector;
55
Chris Masone9be4a9d2011-05-16 15:44:09 -070056namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070057using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070058using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080059using ::testing::ContainerEq;
Paul Stewart7f5ad572012-06-04 15:18:54 -070060using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070061using ::testing::InSequence;
mukesh agrawal784566d2012-08-08 18:32:58 -070062using ::testing::Mock;
Paul Stewart22aa71b2011-09-16 12:15:11 -070063using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070064using ::testing::NiceMock;
65using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070066using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070067using ::testing::SaveArg;
Daniel Erat0818cca2012-12-14 10:16:21 -080068using ::testing::SetArgumentPointee;
Gaurav Shah435de2c2011-11-17 19:01:07 -080069using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080070using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070071using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070072
Chris Masone3bd3c8c2011-06-13 08:20:26 -070073class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070074 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070075 ManagerTest()
Darin Petkov3ec55342012-09-28 14:04:44 +020076 : power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080077 device_info_(new NiceMock<MockDeviceInfo>(
78 control_interface(),
79 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080080 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080081 reinterpret_cast<Manager*>(NULL))),
Paul Stewart3c504012013-01-17 17:49:58 -080082 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()),
Christopher Wiley1057cd72013-02-28 15:21:29 -080083 wifi_provider_(new NiceMock<MockWiFiProvider>()),
84 crypto_util_proxy_(new NiceMock<MockCryptoUtilProxy>(dispatcher(),
85 glib())) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070086 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
87 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080088 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070089 manager(),
90 "null0",
91 "addr0",
92 0));
93 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
94 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080095 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070096 manager(),
97 "null1",
98 "addr1",
99 1));
100 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
101 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800102 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700103 manager(),
104 "null2",
105 "addr2",
106 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800107 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
108 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800109 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800110 manager(),
111 "null3",
112 "addr3",
113 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700114 manager()->connect_profiles_to_rpc_ = false;
Paul Stewart63864b62012-11-07 15:10:55 -0800115 SetRunning(true);
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800116
117 // Replace the manager's adaptor with a quieter one, and one
118 // we can do EXPECT*() against. Passes ownership.
119 manager()->adaptor_.reset(manager_adaptor_);
Paul Stewart3c504012013-01-17 17:49:58 -0800120
121 // Replace the manager's WiFi provider with our mock. Passes
122 // ownership.
123 manager()->wifi_provider_.reset(wifi_provider_);
Christopher Wiley1057cd72013-02-28 15:21:29 -0800124
125 // Replace the manager's crypto util proxy with our mock. Passes
126 // ownership.
127 manager()->crypto_util_proxy_.reset(crypto_util_proxy_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700128 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700129 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700130
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100131 void SetMetrics(Metrics *metrics) {
132 manager()->set_metrics(metrics);
133 }
134
Paul Stewartfdd16072011-09-16 12:41:35 -0700135 bool IsDeviceRegistered(const DeviceRefPtr &device,
136 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700137 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700138 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700139 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700140 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700141 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700142
Paul Stewarta849a3d2011-11-03 05:54:09 -0700143 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
144 manager->profiles_.push_back(profile);
145 }
146
Paul Stewart63864b62012-11-07 15:10:55 -0800147 void SetRunning(bool running) {
148 manager()->running_ = running;
149 }
150
Paul Stewart75225512012-01-26 22:51:33 -0800151 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
152 return manager->ephemeral_profile_;
153 }
154
Paul Stewart307c2502013-03-23 12:32:10 -0700155 vector<ProfileRefPtr> &GetProfiles(Manager *manager) {
156 return manager->profiles_;
157 }
158
Chris Masone6515aab2011-10-12 16:19:09 -0700159 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
160 Profile::Identifier id("rather", "irrelevant");
Chris Masone6515aab2011-10-12 16:19:09 -0700161 FilePath final_path(storage_path());
162 final_path = final_path.Append("test.profile");
163 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
164 storage->set_path(final_path);
165 if (!storage->Open())
166 return NULL;
Paul Stewart5ad16062013-02-21 18:10:48 -0800167 Profile *profile(new Profile(control_interface(),
Thieu Le5133b712013-02-19 14:47:21 -0800168 metrics(),
Paul Stewart5ad16062013-02-21 18:10:48 -0800169 manager,
170 id,
171 "",
172 false));
173 profile->set_storage(storage.release()); // Passes ownership of "storage".
174 return profile; // Passes onwership of "profile".
Chris Masone6515aab2011-10-12 16:19:09 -0700175 }
176
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700177 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
178 const string &profile_identifier,
179 const string &service_name) {
180 GLib glib;
181 KeyFileStore store(&glib);
182 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
183 return store.Open() &&
184 store.SetString(service_name, "rather", "irrelevant") &&
185 store.Close();
186 }
187
188 Error::Type TestCreateProfile(Manager *manager, const string &name) {
189 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800190 string path;
191 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700192 return error.type();
193 }
194
195 Error::Type TestPopAnyProfile(Manager *manager) {
196 Error error;
197 manager->PopAnyProfile(&error);
198 return error.type();
199 }
200
Paul Stewart307c2502013-03-23 12:32:10 -0700201 Error::Type TestPopAllUserProfiles(Manager *manager) {
202 Error error;
203 manager->PopAllUserProfiles(&error);
204 return error.type();
205 }
206
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700207 Error::Type TestPopProfile(Manager *manager, const string &name) {
208 Error error;
209 manager->PopProfile(name, &error);
210 return error.type();
211 }
212
213 Error::Type TestPushProfile(Manager *manager, const string &name) {
214 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800215 string path;
216 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700217 return error.type();
218 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000219
Paul Stewartf3eced92013-04-17 12:18:22 -0700220 Error::Type TestInsertUserProfile(Manager *manager,
221 const string &name,
222 const string &user_hash) {
223 Error error;
224 string path;
225 manager->InsertUserProfile(name, user_hash, &path, &error);
226 return error.type();
227 }
228
Paul Stewartd2e1c362013-03-03 19:06:07 -0800229 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
230 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700231 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800232 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800233 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200234 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700235 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800236 return profile;
237 }
238
239 void AddMockProfileToManager(Manager *manager) {
240 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700241 }
242
Paul Stewartdfa46052012-06-26 09:44:14 -0700243 void CompleteServiceSort() {
244 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
245 dispatcher()->DispatchPendingEvents();
246 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
247 }
248
Paul Stewart49739c02012-08-08 17:24:03 -0700249 RpcIdentifier GetDefaultServiceRpcIdentifier() {
250 return manager()->GetDefaultServiceRpcIdentifier(NULL);
251 }
252
Paul Stewart4d5efb72012-09-17 12:24:34 -0700253 void SetResolver(Resolver *resolver) {
254 manager()->resolver_ = resolver;
255 }
256
257 void SetIgnoredDNSSearchPaths(const string &search_paths) {
258 manager()->SetIgnoredDNSSearchPaths(search_paths, NULL);
259 }
260
261 const string &GetIgnoredDNSSearchPaths() {
262 return manager()->props_.ignored_dns_search_paths;
263 }
264
Paul Stewartd2e1c362013-03-03 19:06:07 -0800265 WiFiServiceRefPtr ReleaseTempMockService() {
266 // Take a reference to hold during this function.
267 WiFiServiceRefPtr temp_service = temp_mock_service_;
268 temp_mock_service_ = NULL;
269 return temp_service;
270 }
271
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700272 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000273 typedef scoped_refptr<MockService> MockServiceRefPtr;
274
Darin Petkova5e07ef2012-07-09 14:27:57 +0200275 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
276 public:
277 ServiceWatcher() {}
278 virtual ~ServiceWatcher() {}
279
280 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
281
282 private:
283 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
284 };
285
Darin Petkovca621542012-07-25 14:25:56 +0200286 class TestProxyFactory : public ProxyFactory {
287 public:
288 TestProxyFactory() {}
289
290 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
291 PowerManagerProxyDelegate */*delegate*/) {
292 return NULL;
293 }
294
295 private:
296 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
297 };
298
Darin Petkov3ec55342012-09-28 14:04:44 +0200299 class TerminationActionTest :
300 public base::SupportsWeakPtr<TerminationActionTest> {
301 public:
302 static const char kActionName[];
303
304 TerminationActionTest() : manager_(NULL) {}
305 virtual ~TerminationActionTest() {}
306
307 MOCK_METHOD1(Done, void(const Error &error));
308
309 void Action() {
310 manager_->TerminationActionComplete("action");
311 }
312
313 void set_manager(Manager *manager) { manager_ = manager; }
314
315 private:
316 Manager *manager_;
317 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
318 };
319
Christopher Wiley1057cd72013-02-28 15:21:29 -0800320 class DestinationVerificationTest :
321 public base::SupportsWeakPtr<DestinationVerificationTest> {
322 public:
323 DestinationVerificationTest() {}
324 virtual ~DestinationVerificationTest() {}
325
326 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
327 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
328 const string &value));
329 private:
330 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
331 };
332
Darin Petkovca621542012-07-25 14:25:56 +0200333 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
334 power_manager_->power_state_ = state;
335 }
336
337 void SetPowerManager() {
338 manager()->set_power_manager(power_manager_.release());
339 }
340
Darin Petkov3ec55342012-09-28 14:04:44 +0200341 HookTable *GetTerminationActions() {
342 return &manager()->termination_actions_;
343 }
344
Darin Petkovca621542012-07-25 14:25:56 +0200345 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
346 manager()->OnPowerStateChanged(state);
347 }
348
Daniel Erat0818cca2012-12-14 10:16:21 -0800349 void OnSuspendImminent(int suspend_id) {
350 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200351 }
352
Daniel Erat0818cca2012-12-14 10:16:21 -0800353 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
354 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200355 }
356
Paul Stewartbfb82552012-10-24 16:48:48 -0700357 vector<string> EnumerateAvailableServices() {
358 return manager()->EnumerateAvailableServices(NULL);
359 }
360
361 vector<string> EnumerateWatchedServices() {
362 return manager()->EnumerateWatchedServices(NULL);
363 }
364
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000365 MockServiceRefPtr MakeAutoConnectableService() {
366 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
367 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800368 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000369 manager());
370 service->MakeFavorite();
371 service->set_connectable(true);
372 return service;
373 }
374
Darin Petkovca621542012-07-25 14:25:56 +0200375 TestProxyFactory proxy_factory_;
376 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700377 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800378 scoped_ptr<MockDeviceInfo> device_info_;
379
Paul Stewartd2e1c362013-03-03 19:06:07 -0800380 // This service is held for the manager, and given ownership in a mock
381 // function. This ensures that when the Manager takes ownership, there
382 // is only one reference left.
383 scoped_refptr<MockWiFiService> temp_mock_service_;
384
Paul Stewart3c504012013-01-17 17:49:58 -0800385 // These pointers are owned by the manager, and only tracked here for
386 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800387 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart3c504012013-01-17 17:49:58 -0800388 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800389 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700390};
391
Darin Petkov3ec55342012-09-28 14:04:44 +0200392const char ManagerTest::TerminationActionTest::kActionName[] = "action";
393
Paul Stewart22aa71b2011-09-16 12:15:11 -0700394bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700395 if (!manager()->sort_services_task_.IsCancelled()) {
396 manager()->SortServicesTask();
397 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700398 return (svc0.get() == manager()->services_[0].get() &&
399 svc1.get() == manager()->services_[1].get());
400}
401
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700402TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700403 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
404 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700405}
406
Chris Masone9be4a9d2011-05-16 15:44:09 -0700407TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700408 ON_CALL(*mock_devices_[0].get(), technology())
409 .WillByDefault(Return(Technology::kEthernet));
410 ON_CALL(*mock_devices_[1].get(), technology())
411 .WillByDefault(Return(Technology::kWifi));
412 ON_CALL(*mock_devices_[2].get(), technology())
413 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700414
Paul Stewart22aa71b2011-09-16 12:15:11 -0700415 manager()->RegisterDevice(mock_devices_[0]);
416 manager()->RegisterDevice(mock_devices_[1]);
417 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700418
Paul Stewart22aa71b2011-09-16 12:15:11 -0700419 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
420 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
421 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700422}
423
Paul Stewarta41e38d2011-11-11 07:47:29 -0800424TEST_F(ManagerTest, DeviceRegistrationAndStart) {
425 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500426 mock_devices_[0]->enabled_persistent_ = true;
427 mock_devices_[1]->enabled_persistent_ = false;
428 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800429 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500430 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800431 .Times(0);
432 manager()->RegisterDevice(mock_devices_[0]);
433 manager()->RegisterDevice(mock_devices_[1]);
434}
435
436TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800437 MockProfile *profile =
438 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800439 DeviceRefPtr device_ref(mock_devices_[0].get());
440 AdoptProfile(manager(), profile); // Passes ownership.
441 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200442 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800443 manager()->RegisterDevice(mock_devices_[0]);
444}
445
Chris Masone9be4a9d2011-05-16 15:44:09 -0700446TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700447 ON_CALL(*mock_devices_[0].get(), technology())
448 .WillByDefault(Return(Technology::kEthernet));
449 ON_CALL(*mock_devices_[1].get(), technology())
450 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700451
Gaurav Shah435de2c2011-11-17 19:01:07 -0800452 manager()->RegisterDevice(mock_devices_[0]);
453 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700454
Paul Stewart22aa71b2011-09-16 12:15:11 -0700455 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
456 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700457
Thieu Le5133b712013-02-19 14:47:21 -0800458 MockProfile *profile =
459 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700460 AdoptProfile(manager(), profile); // Passes ownership.
461
Eric Shienbrood9a245532012-03-07 14:20:39 -0500462 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700463 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800464 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700465 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700466
Eric Shienbrood9a245532012-03-07 14:20:39 -0500467 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700468 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800469 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700470 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700471}
472
473TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700474 // It's much easier and safer to use a real GLib for this test.
475 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700476 Manager manager(control_interface(),
477 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800478 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700479 &glib,
480 run_path(),
481 storage_path(),
482 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700483 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
484 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700485 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700486
Chris Masone9be4a9d2011-05-16 15:44:09 -0700487 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700488 new NiceMock<MockService>(control_interface(),
489 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800490 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700491 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700492 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700493 new NiceMock<MockService>(control_interface(),
494 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800495 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700496 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700497
Darin Petkov457728b2013-01-09 09:49:08 +0100498 string service1_name(mock_service->unique_name());
499 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700500
501 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
502 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700503 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700504 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700505 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700506 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700507 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700508
Chris Masone9d779932011-08-25 16:33:41 -0700509 manager.RegisterService(mock_service);
510 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700511
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800512 Error error;
513 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700514 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700515 EXPECT_EQ(2, ids.size());
516 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
517 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700518
Chris Masone9d779932011-08-25 16:33:41 -0700519 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
520 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
521
522 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700523}
524
Chris Masone6515aab2011-10-12 16:19:09 -0700525TEST_F(ManagerTest, RegisterKnownService) {
526 // It's much easier and safer to use a real GLib for this test.
527 GLib glib;
528 Manager manager(control_interface(),
529 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800530 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700531 &glib,
532 run_path(),
533 storage_path(),
534 string());
535 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
536 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700537 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700538 {
539 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
540 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800541 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700542 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700543 ASSERT_TRUE(profile->AdoptService(service1));
544 ASSERT_TRUE(profile->ContainsService(service1));
545 } // Force destruction of service1.
546
547 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
548 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800549 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700550 &manager));
551 manager.RegisterService(service2);
552 EXPECT_EQ(service2->profile().get(), profile.get());
553 manager.Stop();
554}
555
556TEST_F(ManagerTest, RegisterUnknownService) {
557 // It's much easier and safer to use a real GLib for this test.
558 GLib glib;
559 Manager manager(control_interface(),
560 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800561 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700562 &glib,
563 run_path(),
564 storage_path(),
565 string());
566 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
567 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700568 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700569 {
570 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
571 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800572 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700573 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700574 ASSERT_TRUE(profile->AdoptService(service1));
575 ASSERT_TRUE(profile->ContainsService(service1));
576 } // Force destruction of service1.
577 scoped_refptr<MockService> mock_service2(
578 new NiceMock<MockService>(control_interface(),
579 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800580 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700581 &manager));
582 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100583 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700584 manager.RegisterService(mock_service2);
585 EXPECT_NE(mock_service2->profile().get(), profile.get());
586 manager.Stop();
587}
588
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000589TEST_F(ManagerTest, DeregisterUnregisteredService) {
590 // WiFi assumes that it can deregister a service that is not
591 // registered. (E.g. a hidden service can be deregistered when it
592 // loses its last endpoint, and again when WiFi is Stop()-ed.)
593 //
594 // So test that doing so doesn't cause a crash.
595 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
596 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800597 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000598 manager());
599 manager()->DeregisterService(service);
600}
601
Chris Masonea8a2c252011-06-27 22:16:30 -0700602TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700603 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700604 map<string, ::DBus::Variant> props;
605 Error error(Error::kInvalidProperty, "");
606 {
607 ::DBus::Error dbus_error;
608 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700609 manager()->mutable_store()->SetStringProperty(
610 flimflam::kCheckPortalListProperty,
611 expected,
612 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700613 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700614 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
615 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
616 expected);
617 }
618 {
619 ::DBus::Error dbus_error;
620 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700621 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
622 expected,
623 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700624 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700625 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
626 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
627 expected);
628 }
629}
630
Chris Masone3c3f6a12011-07-01 10:01:41 -0700631TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700632 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800633 manager()->RegisterDevice(mock_devices_[0]);
634 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700635 {
636 map<string, ::DBus::Variant> props;
637 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700638 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700639 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700640 vector < ::DBus::Path> devices =
641 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700642 EXPECT_EQ(2, devices.size());
643 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700644}
645
mukesh agrawal2366eed2012-03-20 18:21:50 -0700646TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700647 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700648 map<string, ::DBus::Variant> props;
649 ::DBus::Error dbus_error;
650 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
651 map<string, ::DBus::Variant>::const_iterator prop =
652 props.find(flimflam::kServicesProperty);
653 ASSERT_FALSE(prop == props.end());
654 const ::DBus::Variant &variant = prop->second;
655 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
656}
657
Chris Masone6791a432011-07-12 13:23:19 -0700658TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700659 Manager manager(control_interface(),
660 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800661 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700662 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700663 run_path(),
664 storage_path(),
665 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700666 scoped_refptr<MockService> s2(new MockService(control_interface(),
667 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800668 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700669 &manager));
670 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700671 {
Chris Masone6515aab2011-10-12 16:19:09 -0700672 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700673 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800674 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700675 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700676 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700677 .WillRepeatedly(Return(true));
678 EXPECT_CALL(*storage, Flush())
679 .Times(AnyNumber())
680 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700681 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700682 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700683 }
Chris Masone6515aab2011-10-12 16:19:09 -0700684 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800685 ProfileRefPtr profile(
686 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700687 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700688
Chris Masone6515aab2011-10-12 16:19:09 -0700689 // Now, move the Service |s2| to another profile.
690 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
691 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700692
693 // Force destruction of the original Profile, to ensure that the Service
694 // is kept alive and populated with data.
695 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700696 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700697 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700698}
699
Paul Stewart7f61e522012-03-22 11:13:45 -0700700TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
701 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800702 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700703 const string kProfileName("profile0");
704 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
705 .WillRepeatedly(Return(kProfileName));
706 AdoptProfile(manager(), mock_profile);
707
708 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
709 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
710 EXPECT_EQ(mock_profile.get(), profile.get());
711}
712
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800713TEST_F(ManagerTest, SetProfileForService) {
714 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800715 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800716 string profile_name0("profile0");
717 EXPECT_CALL(*profile0, GetRpcIdentifier())
718 .WillRepeatedly(Return(profile_name0));
719 AdoptProfile(manager(), profile0);
720 scoped_refptr<MockService> service(new MockService(control_interface(),
721 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800722 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800723 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700724 EXPECT_FALSE(manager()->HasService(service));
725 {
726 Error error;
727 EXPECT_CALL(*profile0, AdoptService(_))
728 .WillOnce(Return(true));
729 // Expect that setting the profile of a service that does not already
730 // have one assigned does not cause a crash.
731 manager()->SetProfileForService(service, "profile0", &error);
732 EXPECT_TRUE(error.IsSuccess());
733 }
734
735 // The service should be registered as a side-effect of the profile being
736 // set for this service.
737 EXPECT_TRUE(manager()->HasService(service));
738
739 // Since we have mocked Profile::AdoptServie() above, the service's
740 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800741 service->set_profile(profile0);
742
743 {
744 Error error;
745 manager()->SetProfileForService(service, "foo", &error);
746 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700747 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800748 }
749
750 {
751 Error error;
752 manager()->SetProfileForService(service, profile_name0, &error);
753 EXPECT_EQ(Error::kInvalidArguments, error.type());
754 EXPECT_EQ("Service is already connected to this profile", error.message());
755 }
756
757 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800758 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800759 string profile_name1("profile1");
760 EXPECT_CALL(*profile1, GetRpcIdentifier())
761 .WillRepeatedly(Return(profile_name1));
762 AdoptProfile(manager(), profile1);
763
764 {
765 Error error;
766 EXPECT_CALL(*profile1, AdoptService(_))
767 .WillOnce(Return(true));
768 EXPECT_CALL(*profile0, AbandonService(_))
769 .WillOnce(Return(true));
770 manager()->SetProfileForService(service, profile_name1, &error);
771 EXPECT_TRUE(error.IsSuccess());
772 }
773}
774
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700775TEST_F(ManagerTest, CreateProfile) {
776 // It's much easier to use real Glib here since we want the storage
777 // side-effects.
778 GLib glib;
779 ScopedTempDir temp_dir;
780 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
781
782 Manager manager(control_interface(),
783 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800784 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700785 &glib,
786 run_path(),
787 storage_path(),
788 temp_dir.path().value());
789
790 // Invalid name should be rejected.
791 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
792
Paul Stewartd0a3b812012-03-28 22:48:22 -0700793 // A profile with invalid characters in it should similarly be rejected.
794 EXPECT_EQ(Error::kInvalidArguments,
795 TestCreateProfile(&manager, "valid_profile"));
796
797 // We should be able to create a machine profile.
798 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700799
Gary Morainb672d352012-04-25 09:19:06 -0700800 // We should succeed in creating a valid user profile. Verify the returned
801 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700802 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700803 {
804 Error error;
805 string path;
806 manager.CreateProfile(kProfile, &path, &error);
807 EXPECT_EQ(Error::kSuccess, error.type());
808 EXPECT_EQ("/profile_rpc", path);
809 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700810
811 // We should fail in creating it a second time (already exists).
812 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
813}
814
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700815// We receive PopProfile when a user logs out, and it should always trigger a
816// MemoryLog Clear() call.
817TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
818 GLib glib;
819 ScopedTempDir temp_dir;
820 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
821 Manager manager(control_interface(),
822 dispatcher(),
823 metrics(),
824 &glib,
825 run_path(),
826 storage_path(),
827 temp_dir.path().value());
828 const char kProfile0[] = "~user/profile0";
829 const char kPurgedMessage[] = "This message should be purged";
830 // Create a profile and push it on the stack, leave one uncreated
831 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
832 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
833
834 // Popping a profile which isn't on top should still clear the log.
835 LOG(INFO) << kPurgedMessage;
836 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
837 kPurgedMessage));
838 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
839 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
840 kPurgedMessage));
841
842 // Popping an invalid profile name should do the same thing.
843 LOG(INFO) << kPurgedMessage;
844 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
845 kPurgedMessage));
846 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
847 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
848 kPurgedMessage));
849
850 // Successful pops also purge the message log.
851 LOG(INFO) << kPurgedMessage;
852 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
853 kPurgedMessage));
854 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
855 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
856 kPurgedMessage));
857}
858
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700859TEST_F(ManagerTest, PushPopProfile) {
860 // It's much easier to use real Glib in creating a Manager for this
861 // test here since we want the storage side-effects.
862 GLib glib;
863 ScopedTempDir temp_dir;
864 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
865 Manager manager(control_interface(),
866 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800867 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700868 &glib,
869 run_path(),
870 storage_path(),
871 temp_dir.path().value());
872
873 // Pushing an invalid profile should fail.
874 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
875
Paul Stewartd0a3b812012-03-28 22:48:22 -0700876 // Pushing a default profile that does not exist should fail.
877 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700878
879 const char kProfile0[] = "~user/profile0";
880 const char kProfile1[] = "~user/profile1";
881
882 // Create a couple of profiles.
883 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
884 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
885
886 // Push these profiles on the stack.
887 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
888 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
889
890 // Pushing a profile a second time should fail.
891 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
892 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
893
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800894 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700895 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800896 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700897
898 // Make sure a profile name that doesn't exist fails.
899 const char kProfile2Id[] = "profile2";
900 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
901 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
902
903 // Create a new service, with a specific storage name.
904 scoped_refptr<MockService> service(
905 new NiceMock<MockService>(control_interface(),
906 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800907 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700908 &manager));
909 const char kServiceName[] = "service_storage_name";
910 EXPECT_CALL(*service.get(), GetStorageIdentifier())
911 .WillRepeatedly(Return(kServiceName));
912 EXPECT_CALL(*service.get(), Load(_))
913 .WillRepeatedly(Return(true));
914
915 // Add this service to the manager -- it should end up in the ephemeral
916 // profile.
917 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800918 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700919
920 // Create storage for a profile that contains the service storage name.
921 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
922 kServiceName));
923
924 // When we push the profile, the service should move away from the
925 // ephemeral profile to this new profile since it has an entry for
926 // this service.
927 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800928 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700929 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
930
931 // Insert another profile that should supersede ownership of the service.
932 const char kProfile3Id[] = "profile3";
933 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
934 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
935 kServiceName));
936 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
937 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
938
939 // Popping an invalid profile name should fail.
940 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
941
942 // Popping an profile that is not at the top of the stack should fail.
943 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
944
945 // Popping the top profile should succeed.
946 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
947
948 // Moreover the service should have switched profiles to profile 2.
949 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
950
951 // Popping the top profile should succeed.
952 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
953
954 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800955 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700956
957 // Pop the remaining two services off the stack.
958 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
959 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
960
961 // Next pop should fail with "stack is empty".
962 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700963
964 const char kMachineProfile0[] = "machineprofile0";
965 const char kMachineProfile1[] = "machineprofile1";
966 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
967 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
968
969 // Should be able to push a machine profile.
970 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
971
972 // Should be able to push a user profile atop a machine profile.
973 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
974
975 // Pushing a system-wide profile on top of a user profile should fail.
976 EXPECT_EQ(Error::kInvalidArguments,
977 TestPushProfile(&manager, kMachineProfile1));
978
979 // However if we pop the user profile, we should be able stack another
980 // machine profile on.
981 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
982 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -0700983
984 // Add two user profiles to the top of the stack.
985 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
986 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
987 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
988 EXPECT_EQ(4, profiles.size());
989
990 // PopAllUserProfiles should remove both user profiles, leaving the two
991 // machine profiles.
992 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
993 EXPECT_EQ(2, profiles.size());
994 EXPECT_TRUE(profiles[0]->GetUser().empty());
995 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewartf3eced92013-04-17 12:18:22 -0700996
997 // Use InsertUserProfile() instead. Although a machine profile is valid
998 // in this state, it cannot be added via InsertUserProfile.
999 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kMachineProfile1));
1000 EXPECT_EQ(Error::kInvalidArguments,
1001 TestInsertUserProfile(&manager, kMachineProfile1, "machinehash1"));
1002 const char kUserHash0[] = "userhash0";
1003 const char kUserHash1[] = "userhash1";
1004 EXPECT_EQ(Error::kSuccess,
1005 TestInsertUserProfile(&manager, kProfile0, kUserHash0));
1006 EXPECT_EQ(Error::kSuccess,
1007 TestInsertUserProfile(&manager, kProfile1, kUserHash1));
1008 EXPECT_EQ(3, profiles.size());
1009 EXPECT_EQ(kUserHash0, profiles[1]->GetUserHash());
1010 EXPECT_EQ(kUserHash1, profiles[2]->GetUserHash());
Paul Stewart5dc40aa2011-10-28 19:43:43 -07001011}
1012
Paul Stewarte73d05c2012-03-29 16:26:05 -07001013TEST_F(ManagerTest, RemoveProfile) {
1014 // It's much easier to use real Glib in creating a Manager for this
1015 // test here since we want the storage side-effects.
1016 GLib glib;
1017 ScopedTempDir temp_dir;
1018 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1019 Manager manager(control_interface(),
1020 dispatcher(),
1021 metrics(),
1022 &glib,
1023 run_path(),
1024 storage_path(),
1025 temp_dir.path().value());
1026
1027 const char kProfile0[] = "profile0";
1028 FilePath profile_path(
1029 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1030
1031 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1032 ASSERT_TRUE(file_util::PathExists(profile_path));
1033
1034 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1035
1036 // Remove should fail since the profile is still on the stack.
1037 {
1038 Error error;
1039 manager.RemoveProfile(kProfile0, &error);
1040 EXPECT_EQ(Error::kInvalidArguments, error.type());
1041 }
1042
1043 // Profile path should still exist.
1044 EXPECT_TRUE(file_util::PathExists(profile_path));
1045
1046 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1047
1048 // This should succeed now that the profile is off the stack.
1049 {
1050 Error error;
1051 manager.RemoveProfile(kProfile0, &error);
1052 EXPECT_EQ(Error::kSuccess, error.type());
1053 }
1054
1055 // Profile path should no longer exist.
1056 EXPECT_FALSE(file_util::PathExists(profile_path));
1057
1058 // Another remove succeeds, due to a foible in file_util::Delete --
1059 // it is not an error to delete a file that does not exist.
1060 {
1061 Error error;
1062 manager.RemoveProfile(kProfile0, &error);
1063 EXPECT_EQ(Error::kSuccess, error.type());
1064 }
1065
1066 // Let's create an error case that will "work". Create a non-empty
1067 // directory in the place of the profile pathname.
1068 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1069 {
1070 Error error;
1071 manager.RemoveProfile(kProfile0, &error);
1072 EXPECT_EQ(Error::kOperationFailed, error.type());
1073 }
1074}
1075
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001076TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1077 // It's much easier to use real Glib in creating a Manager for this
1078 // test here since we want the storage side-effects.
1079 GLib glib;
1080 ScopedTempDir temp_dir;
1081 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1082 Manager manager(control_interface(),
1083 dispatcher(),
1084 metrics(),
1085 &glib,
1086 run_path(),
1087 storage_path(),
1088 temp_dir.path().value());
1089
1090 const char kProfile0[] = "profile0";
1091 FilePath profile_path(
1092 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1093
1094 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1095 ASSERT_TRUE(file_util::PathExists(profile_path));
1096 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1097
1098 // Ensure that even if the backing filestore is removed, we still can't
1099 // create a profile twice.
1100 ASSERT_TRUE(file_util::Delete(profile_path, false));
1101 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1102}
1103
Paul Stewart75225512012-01-26 22:51:33 -08001104// Use this matcher instead of passing RefPtrs directly into the arguments
1105// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1106// system teardown.
1107MATCHER_P(IsRefPtrTo, ref_address, "") {
1108 return arg.get() == ref_address;
1109}
1110
1111TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1112 MockServiceRefPtr s_not_in_profile(
1113 new NiceMock<MockService>(control_interface(),
1114 dispatcher(),
1115 metrics(),
1116 manager()));
1117 MockServiceRefPtr s_not_in_group(
1118 new NiceMock<MockService>(control_interface(),
1119 dispatcher(),
1120 metrics(),
1121 manager()));
1122 MockServiceRefPtr s_configure_fail(
1123 new NiceMock<MockService>(control_interface(),
1124 dispatcher(),
1125 metrics(),
1126 manager()));
1127 MockServiceRefPtr s_configure_succeed(
1128 new NiceMock<MockService>(control_interface(),
1129 dispatcher(),
1130 metrics(),
1131 manager()));
1132
1133 string entry_name("entry_name");
1134 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1135 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1136 .WillRepeatedly(Return("not_entry_name"));
1137 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1138 .WillRepeatedly(Return(entry_name));
1139 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1140 .WillRepeatedly(Return(entry_name));
1141
1142 manager()->RegisterService(s_not_in_profile);
1143 manager()->RegisterService(s_not_in_group);
1144 manager()->RegisterService(s_configure_fail);
1145 manager()->RegisterService(s_configure_succeed);
1146
1147 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001148 new StrictMock<MockProfile>(
1149 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001150 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001151 new StrictMock<MockProfile>(
1152 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001153
1154 s_not_in_group->set_profile(profile1);
1155 s_configure_fail->set_profile(profile1);
1156 s_configure_succeed->set_profile(profile1);
1157
1158 AdoptProfile(manager(), profile0);
1159 AdoptProfile(manager(), profile1);
1160
1161 // No services are a member of this profile.
1162 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1163
1164 // No services that are members of this profile have this entry name.
1165 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1166
1167 // Only services that are members of the profile and group will be abandoned.
1168 EXPECT_CALL(*profile1.get(),
1169 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1170 EXPECT_CALL(*profile1.get(),
1171 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1172 EXPECT_CALL(*profile1.get(),
1173 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1174 .WillOnce(Return(true));
1175 EXPECT_CALL(*profile1.get(),
1176 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1177 .WillOnce(Return(true));
1178
1179 // Never allow services to re-join profile1.
1180 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1181 .WillRepeatedly(Return(false));
1182
1183 // Only allow one of the members of the profile and group to successfully
1184 // join profile0.
1185 EXPECT_CALL(*profile0.get(),
1186 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1187 EXPECT_CALL(*profile0.get(),
1188 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1189 EXPECT_CALL(*profile0.get(),
1190 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1191 .WillOnce(Return(false));
1192 EXPECT_CALL(*profile0.get(),
1193 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1194 .WillOnce(Return(true));
1195
1196 // Expect the failed-to-configure service to have Unload() called on it.
1197 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1198 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1199 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1200 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1201
1202 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1203
1204 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1205 EXPECT_EQ(profile1, s_not_in_group->profile());
1206 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1207
1208 // Since we are using a MockProfile, the profile does not actually change,
1209 // since ConfigureService was not actually called on the service.
1210 EXPECT_EQ(profile1, s_configure_succeed->profile());
1211}
1212
Paul Stewart65512e12012-03-26 18:01:08 -07001213TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1214 MockServiceRefPtr s_will_remove0(
1215 new NiceMock<MockService>(control_interface(),
1216 dispatcher(),
1217 metrics(),
1218 manager()));
1219 MockServiceRefPtr s_will_remove1(
1220 new NiceMock<MockService>(control_interface(),
1221 dispatcher(),
1222 metrics(),
1223 manager()));
1224 MockServiceRefPtr s_will_not_remove0(
1225 new NiceMock<MockService>(control_interface(),
1226 dispatcher(),
1227 metrics(),
1228 manager()));
1229 MockServiceRefPtr s_will_not_remove1(
1230 new NiceMock<MockService>(control_interface(),
1231 dispatcher(),
1232 metrics(),
1233 manager()));
1234
1235 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1236 .Times(4); // Once for each registration.
1237
1238 string entry_name("entry_name");
1239 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1240 .WillRepeatedly(Return(entry_name));
1241 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1242 .WillRepeatedly(Return(entry_name));
1243 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1244 .WillRepeatedly(Return(entry_name));
1245 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1246 .WillRepeatedly(Return(entry_name));
1247
1248 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001249 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001250 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001251 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001252 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001253 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001254 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001255 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001256
1257 // One for each service added above.
1258 ASSERT_EQ(4, manager()->services_.size());
1259
1260 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001261 new StrictMock<MockProfile>(
1262 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001263
1264 s_will_remove0->set_profile(profile);
1265 s_will_remove1->set_profile(profile);
1266 s_will_not_remove0->set_profile(profile);
1267 s_will_not_remove1->set_profile(profile);
1268
1269 AdoptProfile(manager(), profile);
1270
1271 // Deny any of the services re-entry to the profile.
1272 EXPECT_CALL(*profile, ConfigureService(_))
1273 .WillRepeatedly(Return(false));
1274
1275 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1276 .WillOnce(Return(true));
1277 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1278 .WillOnce(Return(true));
1279 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1280 .WillOnce(Return(true));
1281 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1282 .WillOnce(Return(true));
1283
1284 EXPECT_CALL(*s_will_remove0, Unload())
1285 .WillOnce(Return(true));
1286 EXPECT_CALL(*s_will_remove1, Unload())
1287 .WillOnce(Return(true));
1288 EXPECT_CALL(*s_will_not_remove0, Unload())
1289 .WillOnce(Return(false));
1290 EXPECT_CALL(*s_will_not_remove1, Unload())
1291 .WillOnce(Return(false));
1292
1293
1294 // This will cause all the profiles to be unloaded.
1295 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1296
1297 // 2 of the 4 services added above should have been unregistered and
1298 // removed, leaving 2.
1299 EXPECT_EQ(2, manager()->services_.size());
1300 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1301 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1302}
1303
1304TEST_F(ManagerTest, PopProfileWithUnload) {
1305 MockServiceRefPtr s_will_remove0(
1306 new NiceMock<MockService>(control_interface(),
1307 dispatcher(),
1308 metrics(),
1309 manager()));
1310 MockServiceRefPtr s_will_remove1(
1311 new NiceMock<MockService>(control_interface(),
1312 dispatcher(),
1313 metrics(),
1314 manager()));
1315 MockServiceRefPtr s_will_not_remove0(
1316 new NiceMock<MockService>(control_interface(),
1317 dispatcher(),
1318 metrics(),
1319 manager()));
1320 MockServiceRefPtr s_will_not_remove1(
1321 new NiceMock<MockService>(control_interface(),
1322 dispatcher(),
1323 metrics(),
1324 manager()));
1325
1326 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1327 .Times(5); // Once for each registration, and one after profile pop.
1328
1329 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001330 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001331 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001332 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001333 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001334 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001335 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001336 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001337
1338 // One for each service added above.
1339 ASSERT_EQ(4, manager()->services_.size());
1340
1341 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001342 new StrictMock<MockProfile>(
1343 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001344 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001345 new StrictMock<MockProfile>(
1346 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001347
1348 s_will_remove0->set_profile(profile1);
1349 s_will_remove1->set_profile(profile1);
1350 s_will_not_remove0->set_profile(profile1);
1351 s_will_not_remove1->set_profile(profile1);
1352
1353 AdoptProfile(manager(), profile0);
1354 AdoptProfile(manager(), profile1);
1355
1356 // Deny any of the services entry to profile0, so they will all be unloaded.
1357 EXPECT_CALL(*profile0, ConfigureService(_))
1358 .WillRepeatedly(Return(false));
1359
1360 EXPECT_CALL(*s_will_remove0, Unload())
1361 .WillOnce(Return(true));
1362 EXPECT_CALL(*s_will_remove1, Unload())
1363 .WillOnce(Return(true));
1364 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001365 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001366 EXPECT_CALL(*s_will_not_remove1, Unload())
1367 .WillOnce(Return(false));
1368
Philipp Neubeck79173602012-11-13 21:10:09 +01001369 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1370 // profile list.
1371 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1372 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1373
Paul Stewart65512e12012-03-26 18:01:08 -07001374 // This will pop profile1, which should cause all our profiles to unload.
1375 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001376 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001377
1378 // 2 of the 4 services added above should have been unregistered and
1379 // removed, leaving 2.
1380 EXPECT_EQ(2, manager()->services_.size());
1381 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1382 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001383
1384 // Expect the unloaded services to lose their profile reference.
1385 EXPECT_FALSE(s_will_remove0->profile());
1386 EXPECT_FALSE(s_will_remove1->profile());
1387
1388 // If we explicitly deregister a service, the effect should be the same
1389 // with respect to the profile reference.
1390 ASSERT_TRUE(s_will_not_remove0->profile());
1391 manager()->DeregisterService(s_will_not_remove0);
1392 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001393}
1394
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001395TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001396 {
1397 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001398 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1399 flimflam::kOfflineModeProperty,
1400 PropertyStoreTest::kBoolV,
1401 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001402 }
1403 {
1404 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001405 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1406 flimflam::kCountryProperty,
1407 PropertyStoreTest::kStringV,
1408 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001409 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001410 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001411 {
1412 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001413 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1414 flimflam::kCountryProperty,
1415 PropertyStoreTest::kBoolV,
1416 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001417 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001418 }
1419 {
1420 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001421 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1422 flimflam::kOfflineModeProperty,
1423 PropertyStoreTest::kStringV,
1424 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001425 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001426 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001427 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001428 {
1429 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001430 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001431 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001432 flimflam::kEnabledTechnologiesProperty,
1433 PropertyStoreTest::kStringsV,
1434 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001435 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001436 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001437}
1438
mukesh agrawal32399322011-09-01 10:53:43 -07001439TEST_F(ManagerTest, RequestScan) {
1440 {
1441 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001442 manager()->RegisterDevice(mock_devices_[0].get());
1443 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001444 EXPECT_CALL(*mock_devices_[0], technology())
1445 .WillRepeatedly(Return(Technology::kWifi));
Wade Guthrie68d41092013-04-02 12:56:02 -07001446 EXPECT_CALL(*mock_devices_[0], Scan(Device::kFullScan, _));
Joshua Krollda798622012-06-05 12:30:48 -07001447 EXPECT_CALL(*mock_devices_[1], technology())
1448 .WillRepeatedly(Return(Technology::kUnknown));
Wade Guthrie68d41092013-04-02 12:56:02 -07001449 EXPECT_CALL(*mock_devices_[1], Scan(_, _)).Times(0);
1450 manager()->RequestScan(Device::kFullScan, flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001451 }
1452
1453 {
1454 Error error;
Wade Guthrie68d41092013-04-02 12:56:02 -07001455 manager()->RequestScan(Device::kFullScan, "bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001456 EXPECT_EQ(Error::kInvalidArguments, error.type());
1457 }
1458}
1459
Darin Petkovb65c2452012-02-23 15:17:06 +01001460TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001461 KeyValueStore args;
1462 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001463 manager()->GetService(args, &e);
1464 EXPECT_EQ(Error::kInvalidArguments, e.type());
1465 EXPECT_EQ("must specify service type", e.message());
1466}
1467
1468TEST_F(ManagerTest, GetServiceUnknownType) {
1469 KeyValueStore args;
1470 Error e;
1471 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1472 manager()->GetService(args, &e);
1473 EXPECT_EQ(Error::kNotSupported, e.type());
1474 EXPECT_EQ("service type is unsupported", e.message());
1475}
1476
Darin Petkovb65c2452012-02-23 15:17:06 +01001477TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001478 KeyValueStore args;
1479 Error e;
1480 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001481 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001482 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001483 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001484 manager()->GetService(args, &e);
1485 EXPECT_TRUE(e.IsSuccess());
1486}
1487
Darin Petkov33af05c2012-02-28 10:10:30 +01001488TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1489 KeyValueStore args;
1490 Error e;
1491 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001492 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001493 new StrictMock<MockProfile>(
1494 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001495 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001496 ServiceRefPtr service = manager()->GetService(args, &e);
1497 EXPECT_EQ(Error::kNotSupported, e.type());
1498 EXPECT_FALSE(service);
1499}
1500
Darin Petkovb65c2452012-02-23 15:17:06 +01001501TEST_F(ManagerTest, GetServiceVPN) {
1502 KeyValueStore args;
1503 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001504 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001505 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001506 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
Darin Petkov4e02ba22013-04-02 13:44:08 +02001507 args.SetString(flimflam::kNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001508 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001509 new StrictMock<MockProfile>(
1510 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001511 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001512
1513#if defined(DISABLE_VPN)
1514
1515 ServiceRefPtr service = manager()->GetService(args, &e);
1516 EXPECT_EQ(Error::kNotSupported, e.type());
1517 EXPECT_FALSE(service);
1518
1519#else
1520
Paul Stewart7f5ad572012-06-04 15:18:54 -07001521 ServiceRefPtr updated_service;
1522 EXPECT_CALL(*profile, UpdateService(_))
1523 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1524 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001525 EXPECT_CALL(*profile, LoadService(_))
1526 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001527 EXPECT_CALL(*profile, ConfigureService(_))
1528 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001529 ServiceRefPtr service = manager()->GetService(args, &e);
1530 EXPECT_TRUE(e.IsSuccess());
1531 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001532 EXPECT_EQ(service, updated_service);
1533 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001534
1535#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001536}
1537
Darin Petkovc63dcf02012-05-24 11:51:43 +02001538TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1539 KeyValueStore args;
1540 Error e;
1541 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1542 ServiceRefPtr service = manager()->GetService(args, &e);
1543 EXPECT_EQ(Error::kInvalidArguments, e.type());
1544 EXPECT_EQ("Missing WiMAX network id.", e.message());
1545 EXPECT_FALSE(service);
1546}
1547
Darin Petkovd1cd7972012-05-22 15:26:15 +02001548TEST_F(ManagerTest, GetServiceWiMax) {
1549 KeyValueStore args;
1550 Error e;
1551 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001552 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1553 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1554 ServiceRefPtr service = manager()->GetService(args, &e);
1555 EXPECT_TRUE(e.IsSuccess());
1556 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001557}
1558
Paul Stewart7f61e522012-03-22 11:13:45 -07001559TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1560 // Manager calls ActiveProfile() so we need at least one profile installed.
1561 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001562 new NiceMock<MockProfile>(
1563 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001564 AdoptProfile(manager(), profile);
1565
1566 KeyValueStore args;
1567 args.SetString(flimflam::kProfileProperty, "xxx");
1568 Error error;
1569 manager()->ConfigureService(args, &error);
1570 EXPECT_EQ(Error::kInvalidArguments, error.type());
1571 EXPECT_EQ("Invalid profile name xxx", error.message());
1572}
1573
1574TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1575 // Manager calls ActiveProfile() so we need at least one profile installed.
1576 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001577 new NiceMock<MockProfile>(
1578 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001579 AdoptProfile(manager(), profile);
1580
1581 KeyValueStore args;
1582 Error error;
1583 manager()->ConfigureService(args, &error);
1584 EXPECT_EQ(Error::kInvalidArguments, error.type());
1585 EXPECT_EQ("must specify service type", error.message());
1586}
1587
1588// A registered service in the ephemeral profile should be moved to the
1589// active profile as a part of configuration if no profile was explicitly
1590// specified.
1591TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1592 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001593 new NiceMock<MockProfile>(
1594 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001595
1596 AdoptProfile(manager(), profile); // This is now the active profile.
1597
Paul Stewartd2e1c362013-03-03 19:06:07 -08001598 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001599 scoped_refptr<MockWiFiService> service(
1600 new NiceMock<MockWiFiService>(control_interface(),
1601 dispatcher(),
1602 metrics(),
1603 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001604 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001605 ssid,
1606 "",
1607 "",
1608 false));
1609
1610 manager()->RegisterService(service);
1611 service->set_profile(GetEphemeralProfile(manager()));
1612
Paul Stewart3c504012013-01-17 17:49:58 -08001613 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001614 .WillOnce(Return(service));
1615 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1616 .WillOnce(Return(true));
1617 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1618 .WillOnce(Return(true));
1619
1620 KeyValueStore args;
1621 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1622 Error error;
1623 manager()->ConfigureService(args, &error);
1624 EXPECT_TRUE(error.IsSuccess());
1625}
1626
Paul Stewart2c575d22012-12-07 12:28:57 -08001627// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001628// specify a profile, it should be moved from the profile it was previously
1629// in to the specified profile if one was requested.
1630TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1631 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001632 new NiceMock<MockProfile>(
1633 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001634 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001635 new NiceMock<MockProfile>(
1636 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001637
1638 const string kProfileName0 = "profile0";
1639 const string kProfileName1 = "profile1";
1640
1641 EXPECT_CALL(*profile0, GetRpcIdentifier())
1642 .WillRepeatedly(Return(kProfileName0));
1643 EXPECT_CALL(*profile1, GetRpcIdentifier())
1644 .WillRepeatedly(Return(kProfileName1));
1645
1646 AdoptProfile(manager(), profile0);
1647 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1648
Paul Stewartd2e1c362013-03-03 19:06:07 -08001649 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001650 scoped_refptr<MockWiFiService> service(
1651 new NiceMock<MockWiFiService>(control_interface(),
1652 dispatcher(),
1653 metrics(),
1654 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001655 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001656 ssid,
1657 "",
1658 "",
1659 false));
1660
1661 manager()->RegisterService(service);
1662 service->set_profile(profile1);
1663
Paul Stewart3c504012013-01-17 17:49:58 -08001664 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001665 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001666 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1667 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001668 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1669 .WillOnce(Return(true));
1670 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1671 .WillOnce(Return(true));
1672 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1673 .WillOnce(Return(true));
1674
1675 KeyValueStore args;
1676 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1677 args.SetString(flimflam::kProfileProperty, kProfileName0);
1678 Error error;
1679 manager()->ConfigureService(args, &error);
1680 EXPECT_TRUE(error.IsSuccess());
1681 service->set_profile(NULL); // Breaks refcounting loop.
1682}
1683
Paul Stewart2c575d22012-12-07 12:28:57 -08001684// If we configure a service that is already a member of the specified
1685// profile, the Manager should not call LoadService or AdoptService again
1686// on this service.
1687TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1688 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001689 new NiceMock<MockProfile>(
1690 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001691
1692 const string kProfileName0 = "profile0";
1693
1694 EXPECT_CALL(*profile0, GetRpcIdentifier())
1695 .WillRepeatedly(Return(kProfileName0));
1696
1697 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1698
Paul Stewartd2e1c362013-03-03 19:06:07 -08001699 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001700 scoped_refptr<MockWiFiService> service(
1701 new NiceMock<MockWiFiService>(control_interface(),
1702 dispatcher(),
1703 metrics(),
1704 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001705 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001706 ssid,
1707 "",
1708 "",
1709 false));
1710
1711 manager()->RegisterService(service);
1712 service->set_profile(profile0);
1713
Paul Stewart3c504012013-01-17 17:49:58 -08001714 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001715 .WillOnce(Return(service));
1716 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1717 .Times(0);
1718 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1719 .WillOnce(Return(true));
1720 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1721 .Times(0);
1722
1723 KeyValueStore args;
1724 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1725 args.SetString(flimflam::kProfileProperty, kProfileName0);
1726 Error error;
1727 manager()->ConfigureService(args, &error);
1728 EXPECT_TRUE(error.IsSuccess());
1729 service->set_profile(NULL); // Breaks refcounting loop.
1730}
1731
Paul Stewart7f61e522012-03-22 11:13:45 -07001732// An unregistered service should remain unregistered, but its contents should
1733// be saved to the specified profile nonetheless.
1734TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1735 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001736 new NiceMock<MockProfile>(
1737 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001738 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001739 new NiceMock<MockProfile>(
1740 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001741
1742 const string kProfileName0 = "profile0";
1743 const string kProfileName1 = "profile1";
1744
1745 EXPECT_CALL(*profile0, GetRpcIdentifier())
1746 .WillRepeatedly(Return(kProfileName0));
1747 EXPECT_CALL(*profile1, GetRpcIdentifier())
1748 .WillRepeatedly(Return(kProfileName1));
1749
1750 AdoptProfile(manager(), profile0);
1751 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1752
Paul Stewartd2e1c362013-03-03 19:06:07 -08001753 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001754 scoped_refptr<MockWiFiService> service(
1755 new NiceMock<MockWiFiService>(control_interface(),
1756 dispatcher(),
1757 metrics(),
1758 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001759 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001760 ssid,
1761 "",
1762 "",
1763 false));
1764
1765 service->set_profile(profile1);
1766
Paul Stewart3c504012013-01-17 17:49:58 -08001767 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001768 .WillOnce(Return(service));
1769 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1770 .WillOnce(Return(true));
1771 EXPECT_CALL(*profile0, AdoptService(_))
1772 .Times(0);
1773 EXPECT_CALL(*profile1, AdoptService(_))
1774 .Times(0);
1775
1776 KeyValueStore args;
1777 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1778 args.SetString(flimflam::kProfileProperty, kProfileName0);
1779 Error error;
1780 manager()->ConfigureService(args, &error);
1781 EXPECT_TRUE(error.IsSuccess());
1782}
1783
Paul Stewartd2e1c362013-03-03 19:06:07 -08001784TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1785 KeyValueStore args;
1786 Error error;
1787 ServiceRefPtr service =
1788 manager()->ConfigureServiceForProfile("", args, &error);
1789 EXPECT_EQ(Error::kNotSupported, error.type());
1790 EXPECT_EQ("This method only supports WiFi services", error.message());
1791 EXPECT_EQ(NULL, service.get());
1792}
1793
1794TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1795 KeyValueStore args;
1796 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1797 Error error;
1798 ServiceRefPtr service =
1799 manager()->ConfigureServiceForProfile("", args, &error);
1800 EXPECT_EQ(Error::kNotSupported, error.type());
1801 EXPECT_EQ("This method only supports WiFi services", error.message());
1802 EXPECT_EQ(NULL, service.get());
1803}
1804
1805TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1806 KeyValueStore args;
1807 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1808 Error error;
1809 ServiceRefPtr service =
1810 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1811 EXPECT_EQ(Error::kNotFound, error.type());
1812 EXPECT_EQ("Profile specified was not found", error.message());
1813 EXPECT_EQ(NULL, service.get());
1814}
1815
1816TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1817 const string kProfileName0 = "profile0";
1818 const string kProfileName1 = "profile1";
1819 scoped_refptr<MockProfile> profile0(
1820 AddNamedMockProfileToManager(manager(), kProfileName0));
1821
1822 KeyValueStore args;
1823 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1824 args.SetString(flimflam::kProfileProperty, kProfileName1);
1825 Error error;
1826 ServiceRefPtr service =
1827 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1828 EXPECT_EQ(Error::kInvalidArguments, error.type());
1829 EXPECT_EQ("Profile argument does not match that in "
1830 "the configuration arguments", error.message());
1831 EXPECT_EQ(NULL, service.get());
1832}
1833
1834TEST_F(ManagerTest,
1835 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1836 const string kProfileName0 = "profile0";
1837 scoped_refptr<MockProfile> profile0(
1838 AddNamedMockProfileToManager(manager(), kProfileName0));
1839 KeyValueStore args;
1840 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1841 args.SetString(flimflam::kProfileProperty, kProfileName0);
1842
1843 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1844 .WillOnce(Return(WiFiServiceRefPtr()));
1845 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1846 .WillOnce(Return(WiFiServiceRefPtr()));
1847 Error error;
1848 ServiceRefPtr service =
1849 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1850 // Since we didn't set the error in the GetService expectation above...
1851 EXPECT_TRUE(error.IsSuccess());
1852 EXPECT_EQ(NULL, service.get());
1853}
1854
1855TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1856 const string kProfileName0 = "profile0";
1857 scoped_refptr<MockProfile> profile0(
1858 AddNamedMockProfileToManager(manager(), kProfileName0));
1859
1860 KeyValueStore args;
1861 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1862
1863 scoped_refptr<MockWiFiService> mock_service(
1864 new NiceMock<MockWiFiService>(control_interface(),
1865 dispatcher(),
1866 metrics(),
1867 manager(),
1868 wifi_provider_,
1869 vector<uint8_t>(),
1870 flimflam::kModeManaged,
1871 flimflam::kSecurityNone,
1872 false));
1873 ServiceRefPtr mock_service_generic(mock_service.get());
1874 mock_service->set_profile(profile0);
1875 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1876 .WillOnce(Return(WiFiServiceRefPtr()));
1877 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1878 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1879 .WillOnce(Return(true));
1880 Error error;
1881 ServiceRefPtr service =
1882 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1883 EXPECT_TRUE(error.IsSuccess());
1884 EXPECT_EQ(mock_service.get(), service.get());
1885 mock_service->set_profile(NULL); // Breaks reference cycle.
1886}
1887
1888TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
1889 scoped_refptr<MockService> mock_service(
1890 new NiceMock<MockService>(control_interface(),
1891 dispatcher(),
1892 metrics(),
1893 manager()));
1894 const string kGUID = "a guid";
1895 mock_service->set_guid(kGUID);
1896 manager()->RegisterService(mock_service);
1897 ServiceRefPtr mock_service_generic(mock_service.get());
1898
1899 const string kProfileName = "profile";
1900 scoped_refptr<MockProfile> profile(
1901 AddNamedMockProfileToManager(manager(), kProfileName));
1902 mock_service->set_profile(profile);
1903
1904 EXPECT_CALL(*mock_service, technology())
1905 .WillOnce(Return(Technology::kCellular))
1906 .WillOnce(Return(Technology::kWifi));
1907
1908 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
1909 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1910 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1911
1912 KeyValueStore args;
1913 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1914 args.SetString(flimflam::kGuidProperty, kGUID);
1915
1916 // The first attempt should fail because the service reports a technology
1917 // other than "WiFi".
1918 {
1919 Error error;
1920 ServiceRefPtr service =
1921 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1922 EXPECT_EQ(NULL, service.get());
1923 EXPECT_EQ(Error::kNotSupported, error.type());
1924 EXPECT_EQ("This GUID matches a non-WiFi service", error.message());
1925 }
1926
1927 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1928 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1929
1930 {
1931 Error error;
1932 ServiceRefPtr service =
1933 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1934 EXPECT_TRUE(error.IsSuccess());
1935 EXPECT_EQ(mock_service.get(), service.get());
1936 EXPECT_EQ(profile.get(), service->profile().get());
1937 }
1938 mock_service->set_profile(NULL); // Breaks reference cycle.
1939}
1940
1941TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
1942 const string kProfileName = "profile";
1943 scoped_refptr<MockProfile> profile(
1944 AddNamedMockProfileToManager(manager(), kProfileName));
1945
1946 scoped_refptr<MockWiFiService> mock_service(
1947 new NiceMock<MockWiFiService>(control_interface(),
1948 dispatcher(),
1949 metrics(),
1950 manager(),
1951 wifi_provider_,
1952 vector<uint8_t>(),
1953 flimflam::kModeManaged,
1954 flimflam::kSecurityNone,
1955 false));
1956 mock_service->set_profile(profile);
1957 ServiceRefPtr mock_service_generic(mock_service.get());
1958
1959 KeyValueStore args;
1960 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1961 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1962 .WillOnce(Return(mock_service));
1963 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1964 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1965 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1966 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1967
1968 Error error;
1969 ServiceRefPtr service =
1970 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1971 EXPECT_TRUE(error.IsSuccess());
1972 EXPECT_EQ(mock_service.get(), service.get());
1973 EXPECT_EQ(profile.get(), service->profile().get());
1974 mock_service->set_profile(NULL); // Breaks reference cycle.
1975}
1976
1977TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
1978 const string kProfileName = "profile";
1979 scoped_refptr<MockProfile> profile(
1980 AddNamedMockProfileToManager(manager(), kProfileName));
1981
1982 scoped_refptr<MockWiFiService> mock_service(
1983 new NiceMock<MockWiFiService>(control_interface(),
1984 dispatcher(),
1985 metrics(),
1986 manager(),
1987 wifi_provider_,
1988 vector<uint8_t>(),
1989 flimflam::kModeManaged,
1990 flimflam::kSecurityNone,
1991 false));
1992 mock_service->set_profile(GetEphemeralProfile(manager()));
1993 ServiceRefPtr mock_service_generic(mock_service.get());
1994
1995 KeyValueStore args;
1996 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1997 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1998 .WillOnce(Return(mock_service));
1999 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2000 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2001 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
2002
2003 Error error;
2004 ServiceRefPtr service =
2005 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
2006 EXPECT_TRUE(error.IsSuccess());
2007 EXPECT_EQ(mock_service.get(), service.get());
2008 EXPECT_EQ(profile.get(), service->profile().get());
2009 mock_service->set_profile(NULL); // Breaks reference cycle.
2010}
2011
2012TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
2013 const string kProfileName0 = "profile0";
2014 scoped_refptr<MockProfile> profile0(
2015 AddNamedMockProfileToManager(manager(), kProfileName0));
2016 const string kProfileName1 = "profile1";
2017 scoped_refptr<MockProfile> profile1(
2018 AddNamedMockProfileToManager(manager(), kProfileName1));
2019
2020 scoped_refptr<MockWiFiService> mock_service(
2021 new NiceMock<MockWiFiService>(control_interface(),
2022 dispatcher(),
2023 metrics(),
2024 manager(),
2025 wifi_provider_,
2026 vector<uint8_t>(),
2027 flimflam::kModeManaged,
2028 flimflam::kSecurityNone,
2029 false));
2030 manager()->RegisterService(mock_service);
2031 mock_service->set_profile(profile0);
2032 ServiceRefPtr mock_service_generic(mock_service.get());
2033
2034 KeyValueStore args;
2035 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2036 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2037 .WillOnce(Return(mock_service));
2038 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2039 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2040 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2041 // This happens once to make the service loadable for the ConfigureService
2042 // below, and a second time after the service is modified.
2043 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2044 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2045 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2046 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2047
2048 Error error;
2049 ServiceRefPtr service =
2050 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2051 EXPECT_TRUE(error.IsSuccess());
2052 EXPECT_EQ(mock_service.get(), service.get());
2053 mock_service->set_profile(NULL); // Breaks reference cycle.
2054}
2055
2056TEST_F(ManagerTest,
2057 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2058 const string kProfileName0 = "profile0";
2059 scoped_refptr<MockProfile> profile0(
2060 AddNamedMockProfileToManager(manager(), kProfileName0));
2061 const string kProfileName1 = "profile1";
2062 scoped_refptr<MockProfile> profile1(
2063 AddNamedMockProfileToManager(manager(), kProfileName1));
2064
2065 scoped_refptr<MockWiFiService> matching_service(
2066 new StrictMock<MockWiFiService>(control_interface(),
2067 dispatcher(),
2068 metrics(),
2069 manager(),
2070 wifi_provider_,
2071 vector<uint8_t>(),
2072 flimflam::kModeManaged,
2073 flimflam::kSecurityNone,
2074 false));
2075 matching_service->set_profile(profile1);
2076
2077 // We need to get rid of our reference to this mock service as soon
2078 // as Manager::ConfigureServiceForProfile() takes a reference in its
2079 // call to WiFiProvider::CreateTemporaryService(). This way the
2080 // latter function can keep a DCHECK(service->HasOneRef() even in
2081 // unit tests.
2082 temp_mock_service_ =
2083 new NiceMock<MockWiFiService>(control_interface(),
2084 dispatcher(),
2085 metrics(),
2086 manager(),
2087 wifi_provider_,
2088 vector<uint8_t>(),
2089 flimflam::kModeManaged,
2090 flimflam::kSecurityNone,
2091 false);
2092
2093 // Only hold a pointer here so we don't affect the refcount.
2094 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2095
2096 KeyValueStore args;
2097 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2098 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2099 .WillOnce(Return(matching_service));
2100 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2101 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2102 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2103 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2104 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2105 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2106 .Times(1);
2107 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2108 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2109
2110 Error error;
2111 ServiceRefPtr service =
2112 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2113 EXPECT_TRUE(error.IsSuccess());
2114 EXPECT_EQ(NULL, service.get());
2115 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2116}
2117
Paul Stewart7a20aa42013-01-17 12:21:41 -08002118TEST_F(ManagerTest, FindMatchingService) {
2119 KeyValueStore args;
2120 {
2121 Error error;
2122 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2123 EXPECT_EQ(Error::kNotFound, error.type());
2124 }
2125
2126 scoped_refptr<MockService> mock_service0(
2127 new NiceMock<MockService>(control_interface(),
2128 dispatcher(),
2129 metrics(),
2130 manager()));
2131 scoped_refptr<MockService> mock_service1(
2132 new NiceMock<MockService>(control_interface(),
2133 dispatcher(),
2134 metrics(),
2135 manager()));
2136 manager()->RegisterService(mock_service0);
2137 manager()->RegisterService(mock_service1);
2138 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2139 .WillOnce(Return(true))
2140 .WillRepeatedly(Return(false));
2141 {
2142 Error error;
2143 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2144 EXPECT_TRUE(error.IsSuccess());
2145 }
2146 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2147 .WillOnce(Return(true))
2148 .WillRepeatedly(Return(false));
2149 {
2150 Error error;
2151 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2152 EXPECT_TRUE(error.IsSuccess());
2153 }
2154 {
2155 Error error;
2156 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2157 EXPECT_EQ(Error::kNotFound, error.type());
2158 }
2159}
2160
Paul Stewart22aa71b2011-09-16 12:15:11 -07002161TEST_F(ManagerTest, TechnologyOrder) {
2162 Error error;
2163 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2164 string(flimflam::kTypeWifi), &error);
2165 ASSERT_TRUE(error.IsSuccess());
2166 EXPECT_EQ(manager()->GetTechnologyOrder(),
2167 string(flimflam::kTypeEthernet) + "," +
2168 string(flimflam::kTypeWifi));
2169
2170 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2171 string(flimflam::kTypeWifi), &error);
2172 ASSERT_FALSE(error.IsSuccess());
2173 EXPECT_EQ(Error::kInvalidArguments, error.type());
2174 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2175 string(flimflam::kTypeWifi),
2176 manager()->GetTechnologyOrder());
2177}
2178
2179TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002180 // TODO(quiche): Some of these tests would probably fit better in
2181 // service_unittest, since the actual comparison of Services is
2182 // implemented in Service. (crosbug.com/23370)
2183
Paul Stewart22aa71b2011-09-16 12:15:11 -07002184 scoped_refptr<MockService> mock_service0(
2185 new NiceMock<MockService>(control_interface(),
2186 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002187 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002188 manager()));
2189 scoped_refptr<MockService> mock_service1(
2190 new NiceMock<MockService>(control_interface(),
2191 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002192 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002193 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002194
2195 manager()->RegisterService(mock_service0);
2196 manager()->RegisterService(mock_service1);
2197
Darin Petkov457728b2013-01-09 09:49:08 +01002198 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002199 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2200
2201 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002202 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002203 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2204
2205 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002206 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002207 manager()->UpdateService(mock_service1);
2208 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2209
2210 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002211 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002212 manager()->UpdateService(mock_service0);
2213 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2214
2215 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002216 EXPECT_CALL(*mock_service0.get(), technology())
2217 .WillRepeatedly(Return((Technology::kWifi)));
2218 EXPECT_CALL(*mock_service1.get(), technology())
2219 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002220
2221 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002222 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002223 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002224 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2225
2226 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2227 string(flimflam::kTypeEthernet), &error);
2228 EXPECT_TRUE(error.IsSuccess());
2229 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2230
Gaurav Shah435de2c2011-11-17 19:01:07 -08002231 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002232 mock_service0->set_priority(1);
2233 manager()->UpdateService(mock_service0);
2234 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2235
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002236 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002237 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002238 manager()->UpdateService(mock_service1);
2239 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2240
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002241 // Auto-connect.
2242 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002243 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002244 mock_service1->set_auto_connect(false);
2245 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002246 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2247
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002248 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2249 // to any of the others below, so we reset to the default state after
2250 // testing.
2251 EXPECT_CALL(*mock_service1.get(),
2252 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2253 .WillOnce(Return(true))
2254 .WillRepeatedly(Return(false));
2255 manager()->UpdateService(mock_service1);
2256 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2257 manager()->UpdateService(mock_service0);
2258 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2259
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002260 // Connectable.
2261 mock_service1->set_connectable(true);
2262 manager()->UpdateService(mock_service1);
2263 mock_service0->set_connectable(false);
2264 manager()->UpdateService(mock_service0);
2265 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2266
2267 // IsFailed.
2268 EXPECT_CALL(*mock_service0.get(), state())
2269 .WillRepeatedly(Return(Service::kStateIdle));
2270 EXPECT_CALL(*mock_service0.get(), IsFailed())
2271 .WillRepeatedly(Return(false));
2272 manager()->UpdateService(mock_service0);
2273 EXPECT_CALL(*mock_service0.get(), state())
2274 .WillRepeatedly(Return(Service::kStateFailure));
2275 EXPECT_CALL(*mock_service1.get(), IsFailed())
2276 .WillRepeatedly(Return(true));
2277 manager()->UpdateService(mock_service1);
2278 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2279
2280 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002281 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002282 .WillRepeatedly(Return(Service::kStateAssociating));
2283 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002284 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002285 manager()->UpdateService(mock_service1);
2286 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2287
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002288 // Connected.
2289 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002290 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002291 EXPECT_CALL(*mock_service0.get(), IsConnected())
2292 .WillRepeatedly(Return(true));
2293 manager()->UpdateService(mock_service0);
2294 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2295
Paul Stewarta121c442012-06-09 14:12:58 -07002296 // Portal.
2297 EXPECT_CALL(*mock_service1.get(), state())
2298 .WillRepeatedly(Return(Service::kStateConnected));
2299 EXPECT_CALL(*mock_service1.get(), IsConnected())
2300 .WillRepeatedly(Return(true));
2301 manager()->UpdateService(mock_service1);
2302 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2303
Paul Stewart22aa71b2011-09-16 12:15:11 -07002304 manager()->DeregisterService(mock_service0);
2305 manager()->DeregisterService(mock_service1);
2306}
2307
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002308TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002309 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002310 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002311
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002312 scoped_refptr<MockService> mock_service0(
2313 new NiceMock<MockService>(control_interface(),
2314 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002315 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002316 manager()));
2317 scoped_refptr<MockService> mock_service1(
2318 new NiceMock<MockService>(control_interface(),
2319 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002320 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002321 manager()));
2322
2323 scoped_refptr<MockConnection> mock_connection0(
2324 new NiceMock<MockConnection>(device_info_.get()));
2325 scoped_refptr<MockConnection> mock_connection1(
2326 new NiceMock<MockConnection>(device_info_.get()));
2327
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002328 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002329 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002330 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002331 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002332 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002333 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002334
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002335 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002336 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002337
2338 mock_service1->set_priority(1);
2339 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002340 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002341
2342 mock_service1->set_priority(0);
2343 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002344 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002345
Paul Stewartce4ec192012-03-14 12:53:46 -07002346 mock_service0->set_mock_connection(mock_connection0);
2347 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002348
2349 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002350 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002351 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002352
Darin Petkova5e07ef2012-07-09 14:27:57 +02002353 ServiceWatcher service_watcher;
2354 int tag =
2355 manager()->RegisterDefaultServiceCallback(
2356 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2357 service_watcher.AsWeakPtr()));
2358 EXPECT_EQ(1, tag);
2359
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002360 mock_service1->set_priority(1);
2361 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2362 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002363 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002364 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002365 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002366
Darin Petkova5e07ef2012-07-09 14:27:57 +02002367 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002368 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002369 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002370 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002371 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002372 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002373 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002374
Paul Stewartce4ec192012-03-14 12:53:46 -07002375 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002376 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002377 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002378 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002379
2380 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002381 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002382}
2383
Darin Petkova5e07ef2012-07-09 14:27:57 +02002384TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2385 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2386 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2387
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002388 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002389 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002390
2391 scoped_refptr<MockService> mock_service(
2392 new NiceMock<MockService>(
2393 control_interface(), dispatcher(), metrics(), manager()));
2394 ServiceRefPtr service = mock_service;
2395 ServiceRefPtr null_service;
2396
2397 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2398 manager()->NotifyDefaultServiceChanged(null_service);
2399
2400 ServiceWatcher service_watcher1;
2401 ServiceWatcher service_watcher2;
2402 int tag1 =
2403 manager()->RegisterDefaultServiceCallback(
2404 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2405 service_watcher1.AsWeakPtr()));
2406 EXPECT_EQ(1, tag1);
2407 int tag2 =
2408 manager()->RegisterDefaultServiceCallback(
2409 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2410 service_watcher2.AsWeakPtr()));
2411 EXPECT_EQ(2, tag2);
2412
2413 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2414 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2415 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2416 manager()->NotifyDefaultServiceChanged(null_service);
2417
2418 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2419 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2420 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2421 manager()->NotifyDefaultServiceChanged(mock_service);
2422
2423 manager()->DeregisterDefaultServiceCallback(tag1);
2424 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2425 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2426 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2427 manager()->NotifyDefaultServiceChanged(mock_service);
2428 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2429
2430 manager()->DeregisterDefaultServiceCallback(tag2);
2431 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2432 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2433 manager()->NotifyDefaultServiceChanged(mock_service);
2434
2435 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2436 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2437}
2438
Gaurav Shah435de2c2011-11-17 19:01:07 -08002439TEST_F(ManagerTest, AvailableTechnologies) {
2440 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2441 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002442 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002443 manager(),
2444 "null4",
2445 "addr4",
2446 0));
2447 manager()->RegisterDevice(mock_devices_[0]);
2448 manager()->RegisterDevice(mock_devices_[1]);
2449 manager()->RegisterDevice(mock_devices_[2]);
2450 manager()->RegisterDevice(mock_devices_[3]);
2451
2452 ON_CALL(*mock_devices_[0].get(), technology())
2453 .WillByDefault(Return(Technology::kEthernet));
2454 ON_CALL(*mock_devices_[1].get(), technology())
2455 .WillByDefault(Return(Technology::kWifi));
2456 ON_CALL(*mock_devices_[2].get(), technology())
2457 .WillByDefault(Return(Technology::kCellular));
2458 ON_CALL(*mock_devices_[3].get(), technology())
2459 .WillByDefault(Return(Technology::kWifi));
2460
2461 set<string> expected_technologies;
2462 expected_technologies.insert(Technology::NameFromIdentifier(
2463 Technology::kEthernet));
2464 expected_technologies.insert(Technology::NameFromIdentifier(
2465 Technology::kWifi));
2466 expected_technologies.insert(Technology::NameFromIdentifier(
2467 Technology::kCellular));
2468 Error error;
2469 vector<string> technologies = manager()->AvailableTechnologies(&error);
2470
2471 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2472 ContainerEq(expected_technologies));
2473}
2474
2475TEST_F(ManagerTest, ConnectedTechnologies) {
2476 scoped_refptr<MockService> connected_service1(
2477 new NiceMock<MockService>(control_interface(),
2478 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002479 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002480 manager()));
2481 scoped_refptr<MockService> connected_service2(
2482 new NiceMock<MockService>(control_interface(),
2483 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002484 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002485 manager()));
2486 scoped_refptr<MockService> disconnected_service1(
2487 new NiceMock<MockService>(control_interface(),
2488 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002489 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002490 manager()));
2491 scoped_refptr<MockService> disconnected_service2(
2492 new NiceMock<MockService>(control_interface(),
2493 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002494 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002495 manager()));
2496
2497 ON_CALL(*connected_service1.get(), IsConnected())
2498 .WillByDefault(Return(true));
2499 ON_CALL(*connected_service2.get(), IsConnected())
2500 .WillByDefault(Return(true));
2501
2502 manager()->RegisterService(connected_service1);
2503 manager()->RegisterService(connected_service2);
2504 manager()->RegisterService(disconnected_service1);
2505 manager()->RegisterService(disconnected_service2);
2506
2507 manager()->RegisterDevice(mock_devices_[0]);
2508 manager()->RegisterDevice(mock_devices_[1]);
2509 manager()->RegisterDevice(mock_devices_[2]);
2510 manager()->RegisterDevice(mock_devices_[3]);
2511
2512 ON_CALL(*mock_devices_[0].get(), technology())
2513 .WillByDefault(Return(Technology::kEthernet));
2514 ON_CALL(*mock_devices_[1].get(), technology())
2515 .WillByDefault(Return(Technology::kWifi));
2516 ON_CALL(*mock_devices_[2].get(), technology())
2517 .WillByDefault(Return(Technology::kCellular));
2518 ON_CALL(*mock_devices_[3].get(), technology())
2519 .WillByDefault(Return(Technology::kWifi));
2520
2521 mock_devices_[0]->SelectService(connected_service1);
2522 mock_devices_[1]->SelectService(disconnected_service1);
2523 mock_devices_[2]->SelectService(disconnected_service2);
2524 mock_devices_[3]->SelectService(connected_service2);
2525
2526 set<string> expected_technologies;
2527 expected_technologies.insert(Technology::NameFromIdentifier(
2528 Technology::kEthernet));
2529 expected_technologies.insert(Technology::NameFromIdentifier(
2530 Technology::kWifi));
2531 Error error;
2532
2533 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2534 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2535 ContainerEq(expected_technologies));
2536}
2537
2538TEST_F(ManagerTest, DefaultTechnology) {
2539 scoped_refptr<MockService> connected_service(
2540 new NiceMock<MockService>(control_interface(),
2541 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002542 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002543 manager()));
2544 scoped_refptr<MockService> disconnected_service(
2545 new NiceMock<MockService>(control_interface(),
2546 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002547 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002548 manager()));
2549
2550 // Connected. WiFi.
2551 ON_CALL(*connected_service.get(), IsConnected())
2552 .WillByDefault(Return(true));
2553 ON_CALL(*connected_service.get(), state())
2554 .WillByDefault(Return(Service::kStateConnected));
2555 ON_CALL(*connected_service.get(), technology())
2556 .WillByDefault(Return(Technology::kWifi));
2557
2558 // Disconnected. Ethernet.
2559 ON_CALL(*disconnected_service.get(), technology())
2560 .WillByDefault(Return(Technology::kEthernet));
2561
2562 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002563 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002564 Error error;
2565 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2566
2567
2568 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002569 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002570 // Connected service should be brought to the front now.
2571 string expected_technology =
2572 Technology::NameFromIdentifier(Technology::kWifi);
2573 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2574}
2575
Paul Stewart212d60f2012-07-12 10:59:13 -07002576TEST_F(ManagerTest, Stop) {
2577 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002578 new NiceMock<MockProfile>(
2579 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002580 AdoptProfile(manager(), profile);
2581 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002582 new NiceMock<MockService>(control_interface(),
2583 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002584 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002585 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002586 manager()->RegisterService(service);
2587 manager()->RegisterDevice(mock_devices_[0]);
2588 EXPECT_CALL(*profile.get(),
2589 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2590 .WillOnce(Return(true));
Wade Guthrie60a37062013-04-02 11:39:09 -07002591 EXPECT_CALL(*profile.get(), UpdateWiFiProvider(_)).WillOnce(Return(true));
Paul Stewart212d60f2012-07-12 10:59:13 -07002592 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2593 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002594 manager()->Stop();
2595}
2596
mukesh agrawal00917ce2011-11-22 23:56:55 +00002597TEST_F(ManagerTest, UpdateServiceConnected) {
2598 scoped_refptr<MockService> mock_service(
2599 new NiceMock<MockService>(control_interface(),
2600 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002601 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002602 manager()));
2603 manager()->RegisterService(mock_service);
2604 EXPECT_FALSE(mock_service->favorite());
2605 EXPECT_FALSE(mock_service->auto_connect());
2606
Gaurav Shah435de2c2011-11-17 19:01:07 -08002607 EXPECT_CALL(*mock_service.get(), IsConnected())
2608 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002609 manager()->UpdateService(mock_service);
2610 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2611 // to mock out MakeFavorite. And mocking that out would break the
2612 // SortServices test. (crosbug.com/23370)
2613 EXPECT_TRUE(mock_service->favorite());
2614 EXPECT_TRUE(mock_service->auto_connect());
2615}
2616
Thieu Led4e9e552012-02-16 16:26:07 -08002617TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2618 // This tests the case where the user connects to a service that is
2619 // currently associated with a profile. We want to make sure that the
2620 // favorite flag is set and that the flag is saved to the current
2621 // profile.
2622 scoped_refptr<MockService> mock_service(
2623 new NiceMock<MockService>(control_interface(),
2624 dispatcher(),
2625 metrics(),
2626 manager()));
2627 manager()->RegisterService(mock_service);
2628 EXPECT_FALSE(mock_service->favorite());
2629 EXPECT_FALSE(mock_service->auto_connect());
2630
Gary Moraind93615e2012-04-27 11:50:03 -07002631 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002632 new MockProfile(
2633 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002634
Gary Moraind93615e2012-04-27 11:50:03 -07002635 mock_service->set_profile(profile);
2636 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002637 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002638 EXPECT_CALL(*profile,
2639 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002640 manager()->UpdateService(mock_service);
2641 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2642 // to mock out MakeFavorite. And mocking that out would break the
2643 // SortServices test. (crosbug.com/23370)
2644 EXPECT_TRUE(mock_service->favorite());
2645 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002646 // This releases the ref on the mock profile.
2647 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002648}
2649
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002650TEST_F(ManagerTest, SaveSuccessfulService) {
2651 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002652 new StrictMock<MockProfile>(
2653 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002654 AdoptProfile(manager(), profile);
2655 scoped_refptr<MockService> service(
2656 new NiceMock<MockService>(control_interface(),
2657 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002658 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002659 manager()));
2660
2661 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2662 ServiceRefPtr expect_service(service.get());
2663
2664 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2665 .WillOnce(Return(false));
2666 manager()->RegisterService(service);
2667
2668 EXPECT_CALL(*service.get(), state())
2669 .WillRepeatedly(Return(Service::kStateConnected));
2670 EXPECT_CALL(*service.get(), IsConnected())
2671 .WillRepeatedly(Return(true));
2672 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2673 .WillOnce(Return(true));
2674 manager()->UpdateService(service);
2675}
2676
Darin Petkove7c6ad32012-06-29 10:22:09 +02002677TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002678 MockProfile *profile0 =
2679 new MockProfile(control_interface(), metrics(), manager(), "");
2680 MockProfile *profile1 =
2681 new MockProfile(control_interface(), metrics(), manager(), "");
2682 MockProfile *profile2 =
2683 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002684 AdoptProfile(manager(), profile0); // Passes ownership.
2685 AdoptProfile(manager(), profile1); // Passes ownership.
2686 AdoptProfile(manager(), profile2); // Passes ownership.
2687 DeviceRefPtr device_ref(mock_devices_[0].get());
2688 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2689 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2690 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2691 manager()->UpdateDevice(mock_devices_[0]);
2692}
2693
Paul Stewart1b253142012-01-26 14:05:52 -08002694TEST_F(ManagerTest, EnumerateProfiles) {
2695 vector<string> profile_paths;
2696 for (size_t i = 0; i < 10; i++) {
2697 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002698 new StrictMock<MockProfile>(
2699 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002700 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002701 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2702 .WillOnce(Return(profile_paths.back()));
2703 AdoptProfile(manager(), profile);
2704 }
2705
2706 Error error;
2707 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2708 EXPECT_TRUE(error.IsSuccess());
2709 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2710 for (size_t i = 0; i < profile_paths.size(); i++) {
2711 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2712 }
2713}
2714
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002715TEST_F(ManagerTest, AutoConnectOnRegister) {
2716 MockServiceRefPtr service = MakeAutoConnectableService();
2717 EXPECT_CALL(*service.get(), AutoConnect());
2718 manager()->RegisterService(service);
2719 dispatcher()->DispatchPendingEvents();
2720}
2721
2722TEST_F(ManagerTest, AutoConnectOnUpdate) {
2723 MockServiceRefPtr service1 = MakeAutoConnectableService();
2724 service1->set_priority(1);
2725 MockServiceRefPtr service2 = MakeAutoConnectableService();
2726 service2->set_priority(2);
2727 manager()->RegisterService(service1);
2728 manager()->RegisterService(service2);
2729 dispatcher()->DispatchPendingEvents();
2730
2731 EXPECT_CALL(*service1.get(), AutoConnect());
2732 EXPECT_CALL(*service2.get(), state())
2733 .WillRepeatedly(Return(Service::kStateFailure));
2734 EXPECT_CALL(*service2.get(), IsFailed())
2735 .WillRepeatedly(Return(true));
2736 EXPECT_CALL(*service2.get(), IsConnected())
2737 .WillRepeatedly(Return(false));
2738 manager()->UpdateService(service2);
2739 dispatcher()->DispatchPendingEvents();
2740}
2741
2742TEST_F(ManagerTest, AutoConnectOnDeregister) {
2743 MockServiceRefPtr service1 = MakeAutoConnectableService();
2744 service1->set_priority(1);
2745 MockServiceRefPtr service2 = MakeAutoConnectableService();
2746 service2->set_priority(2);
2747 manager()->RegisterService(service1);
2748 manager()->RegisterService(service2);
2749 dispatcher()->DispatchPendingEvents();
2750
2751 EXPECT_CALL(*service1.get(), AutoConnect());
2752 manager()->DeregisterService(service2);
2753 dispatcher()->DispatchPendingEvents();
2754}
2755
Darin Petkov3ec55342012-09-28 14:04:44 +02002756TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2757 MockServiceRefPtr service = MakeAutoConnectableService();
2758 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2759 SetPowerManager();
2760 EXPECT_CALL(*service, AutoConnect()).Times(0);
2761 manager()->RegisterService(service);
2762 dispatcher()->DispatchPendingEvents();
2763}
2764
Darin Petkovca621542012-07-25 14:25:56 +02002765TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2766 MockServiceRefPtr service = MakeAutoConnectableService();
2767 SetPowerState(PowerManagerProxyDelegate::kMem);
2768 SetPowerManager();
2769 EXPECT_CALL(*service, AutoConnect()).Times(0);
2770 manager()->RegisterService(service);
2771 dispatcher()->DispatchPendingEvents();
2772}
2773
2774TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2775 MockServiceRefPtr service = MakeAutoConnectableService();
2776 SetPowerState(PowerManagerProxyDelegate::kOn);
2777 SetPowerManager();
2778 EXPECT_CALL(*service, AutoConnect());
2779 manager()->RegisterService(service);
2780 dispatcher()->DispatchPendingEvents();
2781}
2782
2783TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2784 MockServiceRefPtr service = MakeAutoConnectableService();
2785 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2786 SetPowerManager();
2787 EXPECT_CALL(*service, AutoConnect());
2788 manager()->RegisterService(service);
2789 dispatcher()->DispatchPendingEvents();
2790}
2791
Paul Stewart63864b62012-11-07 15:10:55 -08002792TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2793 SetRunning(false);
2794 MockServiceRefPtr service = MakeAutoConnectableService();
2795 EXPECT_CALL(*service, AutoConnect()).Times(0);
2796 manager()->RegisterService(service);
2797 dispatcher()->DispatchPendingEvents();
2798}
2799
Darin Petkovca621542012-07-25 14:25:56 +02002800TEST_F(ManagerTest, OnPowerStateChanged) {
2801 MockServiceRefPtr service = MakeAutoConnectableService();
2802 SetPowerState(PowerManagerProxyDelegate::kOn);
2803 SetPowerManager();
2804 EXPECT_CALL(*service, AutoConnect());
2805 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002806 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002807 dispatcher()->DispatchPendingEvents();
2808
mukesh agrawal784566d2012-08-08 18:32:58 -07002809 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002810 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2811 EXPECT_CALL(*service, AutoConnect());
2812 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002813 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002814
mukesh agrawal784566d2012-08-08 18:32:58 -07002815 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002816 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2817 EXPECT_CALL(*service, AutoConnect()).Times(0);
2818 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002819 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002820}
2821
Darin Petkov3ec55342012-09-28 14:04:44 +02002822TEST_F(ManagerTest, AddTerminationAction) {
2823 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002824 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002825 SetPowerManager();
2826 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2827 manager()->AddTerminationAction("action1", base::Closure());
2828 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2829 manager()->AddTerminationAction("action2", base::Closure());
2830}
2831
2832TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002833 const char kKey1[] = "action1";
2834 const char kKey2[] = "action2";
2835 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002836
2837 MockPowerManager &power_manager = *power_manager_;
2838 SetPowerManager();
2839
2840 // Removing an action when the hook table is empty should not result in any
2841 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002842 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002843 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2844 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2845 manager()->RemoveTerminationAction("unknown");
2846 Mock::VerifyAndClearExpectations(&power_manager);
2847
Daniel Eratf9753672013-01-24 10:17:02 -08002848 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2849 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002850 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002851 manager()->AddTerminationAction(kKey1, base::Closure());
2852 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2853 manager()->AddTerminationAction(kKey2, base::Closure());
2854
2855 // Removing an action that ends up with a non-empty hook table should not
2856 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002857 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002858 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2859 manager()->RemoveTerminationAction(kKey1);
2860 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2861 Mock::VerifyAndClearExpectations(&power_manager);
2862
2863 // Removing the last action should trigger unregistering from the power
2864 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002865 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2866 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002867 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2868 manager()->RemoveTerminationAction(kKey2);
2869 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2870}
2871
2872TEST_F(ManagerTest, RunTerminationActions) {
2873 TerminationActionTest test_action;
2874 const string kActionName = "action";
2875
2876 EXPECT_CALL(test_action, Done(_));
2877 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2878 test_action.AsWeakPtr()));
2879
2880 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2881 Bind(&TerminationActionTest::Action,
2882 test_action.AsWeakPtr()));
2883 test_action.set_manager(manager());
2884 EXPECT_CALL(test_action, Done(_));
2885 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2886 test_action.AsWeakPtr()));
2887}
2888
Daniel Erat0818cca2012-12-14 10:16:21 -08002889TEST_F(ManagerTest, OnSuspendImminent) {
2890 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002891 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08002892 EXPECT_CALL(*power_manager_,
2893 ReportSuspendReadiness(
2894 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002895 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002896 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02002897}
2898
2899TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002900 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02002901 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08002902 EXPECT_CALL(*power_manager_,
2903 ReportSuspendReadiness(
2904 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002905 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002906 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02002907}
2908
Paul Stewartc681fa02012-03-02 19:40:04 -08002909TEST_F(ManagerTest, RecheckPortal) {
2910 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
2911 .WillOnce(Return(false));
2912 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
2913 .WillOnce(Return(true));
2914 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
2915 .Times(0);
2916
2917 manager()->RegisterDevice(mock_devices_[0]);
2918 manager()->RegisterDevice(mock_devices_[1]);
2919 manager()->RegisterDevice(mock_devices_[2]);
2920
2921 manager()->RecheckPortal(NULL);
2922}
2923
Paul Stewartd215af62012-04-24 23:25:50 -07002924TEST_F(ManagerTest, RecheckPortalOnService) {
2925 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
2926 dispatcher(),
2927 metrics(),
2928 manager());
2929 EXPECT_CALL(*mock_devices_[0].get(),
2930 IsConnectedToService(IsRefPtrTo(service)))
2931 .WillOnce(Return(false));
2932 EXPECT_CALL(*mock_devices_[1].get(),
2933 IsConnectedToService(IsRefPtrTo(service)))
2934 .WillOnce(Return(true));
2935 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
2936 .WillOnce(Return(true));
2937 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
2938 .Times(0);
2939
2940 manager()->RegisterDevice(mock_devices_[0]);
2941 manager()->RegisterDevice(mock_devices_[1]);
2942 manager()->RegisterDevice(mock_devices_[2]);
2943
2944 manager()->RecheckPortalOnService(service);
2945}
2946
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002947TEST_F(ManagerTest, GetDefaultService) {
2948 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002949 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002950
2951 scoped_refptr<MockService> mock_service(
2952 new NiceMock<MockService>(control_interface(),
2953 dispatcher(),
2954 metrics(),
2955 manager()));
2956
2957 manager()->RegisterService(mock_service);
2958 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002959 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002960
2961 scoped_refptr<MockConnection> mock_connection(
2962 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002963 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002964 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002965 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002966
Paul Stewartce4ec192012-03-14 12:53:46 -07002967 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002968 manager()->DeregisterService(mock_service);
2969}
2970
Paul Stewart13ed2252012-03-21 12:52:46 -07002971TEST_F(ManagerTest, GetServiceWithGUID) {
2972 scoped_refptr<MockService> mock_service0(
2973 new NiceMock<MockService>(control_interface(),
2974 dispatcher(),
2975 metrics(),
2976 manager()));
2977
2978 scoped_refptr<MockService> mock_service1(
2979 new NiceMock<MockService>(control_interface(),
2980 dispatcher(),
2981 metrics(),
2982 manager()));
2983
Paul Stewartcb59fed2012-03-21 21:14:46 -07002984 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
2985 .Times(0);
2986 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
2987 .Times(0);
2988
Paul Stewart13ed2252012-03-21 12:52:46 -07002989 manager()->RegisterService(mock_service0);
2990 manager()->RegisterService(mock_service1);
2991
2992 const string kGUID0 = "GUID0";
2993 const string kGUID1 = "GUID1";
2994
2995 {
2996 Error error;
2997 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
2998 EXPECT_FALSE(error.IsSuccess());
2999 EXPECT_FALSE(service);
3000 }
3001
3002 KeyValueStore args;
3003 args.SetString(flimflam::kGuidProperty, kGUID1);
3004
3005 {
3006 Error error;
3007 ServiceRefPtr service = manager()->GetService(args, &error);
3008 EXPECT_EQ(Error::kInvalidArguments, error.type());
3009 EXPECT_FALSE(service);
3010 }
3011
3012 mock_service0->set_guid(kGUID0);
3013 mock_service1->set_guid(kGUID1);
3014
3015 {
3016 Error error;
3017 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
3018 EXPECT_TRUE(error.IsSuccess());
3019 EXPECT_EQ(mock_service0.get(), service.get());
3020 }
3021
3022 {
3023 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07003024 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3025 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003026 ServiceRefPtr service = manager()->GetService(args, &error);
3027 EXPECT_TRUE(error.IsSuccess());
3028 EXPECT_EQ(mock_service1.get(), service.get());
3029 }
3030
3031 manager()->DeregisterService(mock_service0);
3032 manager()->DeregisterService(mock_service1);
3033}
3034
Gary Morain028545d2012-04-07 14:55:52 -07003035
3036TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003037 EXPECT_FALSE(manager()->IsOnline());
3038 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3039
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003040 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003041 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003042 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3043 .Times(AnyNumber());
3044 scoped_refptr<MockService> mock_service0(
3045 new NiceMock<MockService>(control_interface(),
3046 dispatcher(),
3047 metrics(),
3048 manager()));
3049
3050 scoped_refptr<MockService> mock_service1(
3051 new NiceMock<MockService>(control_interface(),
3052 dispatcher(),
3053 metrics(),
3054 manager()));
3055
3056 EXPECT_CALL(*mock_service0.get(), IsConnected())
3057 .WillRepeatedly(Return(false));
3058 EXPECT_CALL(*mock_service1.get(), IsConnected())
3059 .WillRepeatedly(Return(false));
3060
3061 manager()->RegisterService(mock_service0);
3062 manager()->RegisterService(mock_service1);
3063
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003064 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003065 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3066
3067 manager()->DeregisterService(mock_service0);
3068 manager()->DeregisterService(mock_service1);
3069}
3070
3071TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003072 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003073 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003074 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3075 .Times(AnyNumber());
3076 scoped_refptr<MockService> mock_service0(
3077 new NiceMock<MockService>(control_interface(),
3078 dispatcher(),
3079 metrics(),
3080 manager()));
3081
3082 scoped_refptr<MockService> mock_service1(
3083 new NiceMock<MockService>(control_interface(),
3084 dispatcher(),
3085 metrics(),
3086 manager()));
3087
3088 EXPECT_CALL(*mock_service0.get(), IsConnected())
3089 .WillRepeatedly(Return(false));
3090 EXPECT_CALL(*mock_service1.get(), IsConnected())
3091 .WillRepeatedly(Return(true));
3092 EXPECT_CALL(*mock_service0.get(), state())
3093 .WillRepeatedly(Return(Service::kStateIdle));
3094 EXPECT_CALL(*mock_service1.get(), state())
3095 .WillRepeatedly(Return(Service::kStateConnected));
3096
3097 manager()->RegisterService(mock_service0);
3098 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003099 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003100
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003101 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003102 EXPECT_EQ("online", manager()->CalculateState(NULL));
3103
3104 manager()->DeregisterService(mock_service0);
3105 manager()->DeregisterService(mock_service1);
3106}
3107
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003108TEST_F(ManagerTest, StartupPortalList) {
3109 // Simulate loading value from the default profile.
3110 const string kProfileValue("wifi,vpn");
3111 manager()->props_.check_portal_list = kProfileValue;
3112
3113 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3114 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3115 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3116
3117 const string kStartupValue("cellular,ethernet");
3118 manager()->SetStartupPortalList(kStartupValue);
3119 // Ensure profile value is not overwritten, so when we save the default
3120 // profile, the correct value will still be written.
3121 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3122
3123 // However we should read back a different list.
3124 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3125 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3126 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3127
3128 const string kRuntimeValue("ppp");
3129 // Setting a runtime value over the control API should overwrite both
3130 // the profile value and what we read back.
3131 Error error;
3132 manager()->mutable_store()->SetStringProperty(
3133 flimflam::kCheckPortalListProperty,
3134 kRuntimeValue,
3135 &error);
3136 ASSERT_TRUE(error.IsSuccess());
3137 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3138 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3139 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3140 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3141}
3142
Paul Stewart036dba02012-08-07 12:34:41 -07003143TEST_F(ManagerTest, LinkMonitorEnabled) {
3144 const string kEnabledTechnologies("wifi,vpn");
3145 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3146 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3147 EXPECT_FALSE(
3148 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3149}
3150
Paul Stewart85aea152013-01-22 09:31:56 -08003151TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003152 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003153 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003154 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003155 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003156 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003157 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3158 AdoptProfile(manager(), profile);
3159 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3160 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3161 scoped_ptr<MockStore> store1(new MockStore);
3162 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3163}
3164
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003165TEST_F(ManagerTest, EnableTechnology) {
3166 Error error(Error::kOperationInitiated);
3167 ResultCallback callback;
3168 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3169 EXPECT_TRUE(error.IsSuccess());
3170
Joshua Krollda798622012-06-05 12:30:48 -07003171 ON_CALL(*mock_devices_[0], technology())
3172 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003173
3174 manager()->RegisterDevice(mock_devices_[0]);
3175
3176 // Device is enabled, so expect operation is successful.
3177 mock_devices_[0]->enabled_ = true;
3178 error.Populate(Error::kOperationInitiated);
3179 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3180 EXPECT_TRUE(error.IsSuccess());
3181
3182 // Device is disabled, so expect operation in progress.
3183 mock_devices_[0]->enabled_ = false;
3184 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3185 error.Populate(Error::kOperationInitiated);
3186 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3187 EXPECT_TRUE(error.IsOngoing());
3188}
3189
3190TEST_F(ManagerTest, DisableTechnology) {
3191 Error error(Error::kOperationInitiated);
3192 ResultCallback callback;
3193 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3194 EXPECT_TRUE(error.IsSuccess());
3195
Joshua Krollda798622012-06-05 12:30:48 -07003196 ON_CALL(*mock_devices_[0], technology())
3197 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003198
3199 manager()->RegisterDevice(mock_devices_[0]);
3200
3201 // Device is disabled, so expect operation is successful.
3202 error.Populate(Error::kOperationInitiated);
3203 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3204 EXPECT_TRUE(error.IsSuccess());
3205
3206 // Device is enabled, so expect operation in progress.
3207 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3208 mock_devices_[0]->enabled_ = true;
3209 error.Populate(Error::kOperationInitiated);
3210 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3211 EXPECT_TRUE(error.IsOngoing());
3212}
3213
Paul Stewart4d5efb72012-09-17 12:24:34 -07003214TEST_F(ManagerTest, IgnoredSearchList) {
3215 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
3216 SetResolver(resolver.get());
3217 vector<string> ignored_paths;
3218 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3219 SetIgnoredDNSSearchPaths("");
3220 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3221
3222 const string kIgnored0 = "chromium.org";
3223 ignored_paths.push_back(kIgnored0);
3224 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3225 SetIgnoredDNSSearchPaths(kIgnored0);
3226 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3227
3228 const string kIgnored1 = "google.com";
3229 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3230 ignored_paths.push_back(kIgnored1);
3231 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3232 SetIgnoredDNSSearchPaths(kIgnoredSum);
3233 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3234
3235 SetResolver(Resolver::GetInstance());
3236}
3237
Paul Stewartbfb82552012-10-24 16:48:48 -07003238TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3239 // Test to make sure that every service state-change causes the
3240 // Manager to emit a new service list.
3241 scoped_refptr<MockService> mock_service(
3242 new NiceMock<MockService>(control_interface(),
3243 dispatcher(),
3244 metrics(),
3245 manager()));
3246 EXPECT_CALL(*mock_service, state())
3247 .WillRepeatedly(Return(Service::kStateIdle));
3248
3249 manager()->RegisterService(mock_service);
3250 EXPECT_CALL(
3251 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3252 flimflam::kServicesProperty, _)).Times(1);
3253 EXPECT_CALL(
3254 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3255 flimflam::kServiceWatchListProperty, _)).Times(1);
3256 CompleteServiceSort();
3257
3258 Mock::VerifyAndClearExpectations(manager_adaptor_);
3259 EXPECT_CALL(
3260 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3261 flimflam::kServicesProperty, _)).Times(1);
3262 EXPECT_CALL(
3263 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3264 flimflam::kServiceWatchListProperty, _)).Times(1);
3265 manager()->UpdateService(mock_service.get());
3266 CompleteServiceSort();
3267
3268 manager()->DeregisterService(mock_service);
3269}
3270
3271TEST_F(ManagerTest, EnumerateServices) {
3272 scoped_refptr<MockService> mock_service(
3273 new NiceMock<MockService>(control_interface(),
3274 dispatcher(),
3275 metrics(),
3276 manager()));
3277 manager()->RegisterService(mock_service);
3278
3279 EXPECT_CALL(*mock_service, state())
3280 .WillRepeatedly(Return(Service::kStateConnected));
3281 EXPECT_CALL(*mock_service, IsVisible())
3282 .WillRepeatedly(Return(false));
3283 EXPECT_TRUE(EnumerateAvailableServices().empty());
3284 EXPECT_TRUE(EnumerateWatchedServices().empty());
3285
3286 EXPECT_CALL(*mock_service, state())
3287 .WillRepeatedly(Return(Service::kStateIdle));
3288 EXPECT_TRUE(EnumerateAvailableServices().empty());
3289 EXPECT_TRUE(EnumerateWatchedServices().empty());
3290
3291 EXPECT_CALL(*mock_service, IsVisible())
3292 .WillRepeatedly(Return(true));
3293 Service::ConnectState unwatched_states[] = {
3294 Service::kStateUnknown,
3295 Service::kStateIdle,
3296 Service::kStateFailure
3297 };
3298 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3299 EXPECT_CALL(*mock_service, state())
3300 .WillRepeatedly(Return(unwatched_states[i]));
3301 EXPECT_FALSE(EnumerateAvailableServices().empty());
3302 EXPECT_TRUE(EnumerateWatchedServices().empty());
3303 }
3304
3305 Service::ConnectState watched_states[] = {
3306 Service::kStateAssociating,
3307 Service::kStateConfiguring,
3308 Service::kStateConnected,
3309 Service::kStateDisconnected,
3310 Service::kStatePortal,
3311 Service::kStateOnline
3312 };
3313 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3314 EXPECT_CALL(*mock_service, state())
3315 .WillRepeatedly(Return(watched_states[i]));
3316 EXPECT_FALSE(EnumerateAvailableServices().empty());
3317 EXPECT_FALSE(EnumerateWatchedServices().empty());
3318 }
3319
3320 manager()->DeregisterService(mock_service);
3321}
3322
Paul Stewart39db5ca2013-03-18 14:15:17 -07003323TEST_F(ManagerTest, ConnectToBestServices) {
3324 scoped_refptr<MockService> wifi_service0(
3325 new NiceMock<MockService>(control_interface(),
3326 dispatcher(),
3327 metrics(),
3328 manager()));
3329 EXPECT_CALL(*wifi_service0.get(), state())
3330 .WillRepeatedly(Return(Service::kStateIdle));
3331 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3332 .WillRepeatedly(Return(false));
3333 wifi_service0->set_connectable(true);
3334 wifi_service0->set_auto_connect(true);
3335 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3336 EXPECT_CALL(*wifi_service0.get(), technology())
3337 .WillRepeatedly(Return(Technology::kWifi));
3338
3339 scoped_refptr<MockService> wifi_service1(
3340 new NiceMock<MockService>(control_interface(),
3341 dispatcher(),
3342 metrics(),
3343 manager()));
3344 EXPECT_CALL(*wifi_service1.get(), state())
3345 .WillRepeatedly(Return(Service::kStateIdle));
3346 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3347 .WillRepeatedly(Return(false));
3348 wifi_service1->set_auto_connect(true);
3349 wifi_service1->set_connectable(true);
3350 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3351 EXPECT_CALL(*wifi_service1.get(), technology())
3352 .WillRepeatedly(Return(Technology::kWifi));
3353
3354 scoped_refptr<MockService> wifi_service2(
3355 new NiceMock<MockService>(control_interface(),
3356 dispatcher(),
3357 metrics(),
3358 manager()));
3359 EXPECT_CALL(*wifi_service2.get(), state())
3360 .WillRepeatedly(Return(Service::kStateConnected));
3361 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3362 .WillRepeatedly(Return(true));
3363 wifi_service2->set_auto_connect(true);
3364 wifi_service2->set_connectable(true);
3365 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3366 EXPECT_CALL(*wifi_service2.get(), technology())
3367 .WillRepeatedly(Return(Technology::kWifi));
3368
3369 manager()->RegisterService(wifi_service0);
3370 manager()->RegisterService(wifi_service1);
3371 manager()->RegisterService(wifi_service2);
3372
3373 CompleteServiceSort();
3374 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3375
3376 scoped_refptr<MockService> cell_service(
3377 new NiceMock<MockService>(control_interface(),
3378 dispatcher(),
3379 metrics(),
3380 manager()));
3381
3382 EXPECT_CALL(*cell_service.get(), state())
3383 .WillRepeatedly(Return(Service::kStateConnected));
3384 EXPECT_CALL(*cell_service.get(), IsConnected())
3385 .WillRepeatedly(Return(true));
3386 wifi_service2->set_auto_connect(true);
3387 cell_service->set_connectable(true);
3388 EXPECT_CALL(*cell_service.get(), technology())
3389 .WillRepeatedly(Return(Technology::kCellular));
3390 manager()->RegisterService(cell_service);
3391
3392 scoped_refptr<MockService> vpn_service(
3393 new NiceMock<MockService>(control_interface(),
3394 dispatcher(),
3395 metrics(),
3396 manager()));
3397
3398 EXPECT_CALL(*vpn_service.get(), state())
3399 .WillRepeatedly(Return(Service::kStateIdle));
3400 EXPECT_CALL(*vpn_service.get(), IsConnected())
3401 .WillRepeatedly(Return(false));
3402 wifi_service2->set_auto_connect(false);
3403 vpn_service->set_connectable(true);
3404 EXPECT_CALL(*vpn_service.get(), technology())
3405 .WillRepeatedly(Return(Technology::kVPN));
3406 manager()->RegisterService(vpn_service);
3407
3408 // The connected services should be at the top.
3409 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3410
mukesh agrawaldc7b8442012-09-27 13:48:14 -07003411 EXPECT_CALL(*wifi_service0.get(), Connect(_, _)).Times(1);
3412 EXPECT_CALL(*wifi_service1.get(), Connect(_, _)).Times(0); // Lower prio.
3413 EXPECT_CALL(*wifi_service2.get(), Connect(_, _)).Times(0); // Lower prio.
3414 EXPECT_CALL(*cell_service.get(), Connect(_, _)).Times(0); // Is connected.
3415 EXPECT_CALL(*vpn_service.get(), Connect(_, _)).Times(0); // Not autoconnect.
Paul Stewart39db5ca2013-03-18 14:15:17 -07003416
3417 manager()->ConnectToBestServices(NULL);
3418 dispatcher()->DispatchPendingEvents();
3419
3420 // After this operation, since the Connect calls above are mocked and
3421 // no actual state changes have occurred, we should expect that the
3422 // service sorting order will not have changed.
3423 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3424}
3425
Christopher Wiley1057cd72013-02-28 15:21:29 -08003426TEST_F(ManagerTest, VerifyDestination) {
3427 const string kFakeCertificate("fake cert");
3428 const string kFakePublicKey("fake public key");
3429 const string kFakeNonce("fake public key");
3430 const string kFakeSignedData("fake signed data");
3431 const string kFakeUdn("fake udn");
3432 const char kSSIDStr[] = "fake ssid";
3433 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
3434 const string kFakeData("muffin man");
3435 scoped_refptr<MockWiFiService> mock_destination(
3436 new NiceMock<MockWiFiService>(control_interface(),
3437 dispatcher(),
3438 metrics(),
3439 manager(),
3440 wifi_provider_,
3441 kSSID,
3442 "",
3443 "none",
3444 false));
3445 manager()->RegisterService(mock_destination);
3446 StrictMock<DestinationVerificationTest> dv_test;
3447
3448 // Verify that if we're not connected to anything, verification fails.
3449 {
3450 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3451 kFakePublicKey,
3452 kFakeNonce,
3453 kFakeSignedData,
3454 kFakeUdn,
3455 kSSID,
3456 _,
3457 _,
3458 _))
3459 .Times(0);
3460 Error error(Error::kOperationInitiated);
3461 ResultBoolCallback cb = Bind(
3462 &DestinationVerificationTest::ResultBoolCallbackStub,
3463 dv_test.AsWeakPtr());
3464 manager()->VerifyDestination(kFakeCertificate,
3465 kFakePublicKey,
3466 kFakeNonce,
3467 kFakeSignedData,
3468 kFakeUdn,
3469 cb,
3470 &error);
3471 EXPECT_TRUE(error.IsFailure());
3472 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3473 }
3474
3475 // Making the service look online will let service lookup in
3476 // VerifyDestinatoin succeed.
3477 EXPECT_CALL(*mock_destination.get(), IsConnected())
3478 .WillRepeatedly(Return(true));
3479
3480 // Lead off by verifying that the basic VerifyDestination flow works.
3481 {
3482 ResultBoolCallback passed_down_callback;
3483 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3484 kFakePublicKey,
3485 kFakeNonce,
3486 kFakeSignedData,
3487 kFakeUdn,
3488 kSSID,
3489 _,
3490 _,
3491 _))
3492 .Times(1)
3493 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3494 // Ask the manager to verify the current destination. This should look
3495 // up our previously registered service, and pass some metadata about
3496 // that service down to the CryptoUtilProxy to verify.
3497 Error error(Error::kOperationInitiated);
3498 ResultBoolCallback cb = Bind(
3499 &DestinationVerificationTest::ResultBoolCallbackStub,
3500 dv_test.AsWeakPtr());
3501 manager()->VerifyDestination(kFakeCertificate,
3502 kFakePublicKey,
3503 kFakeNonce,
3504 kFakeSignedData,
3505 kFakeUdn,
3506 cb,
3507 &error);
3508 // We assert here, because if the operation is not ongoing, it is
3509 // inconsistent with shim behavior to call the callback anyway.
3510 ASSERT_TRUE(error.IsOngoing());
3511 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3512 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3513 // Call the callback passed into the CryptoUtilProxy, which
3514 // should find its way into the callback passed into the manager.
3515 // In real code, that callback passed into the manager is from the
3516 // DBus adaptor.
3517 Error e;
3518 passed_down_callback.Run(e, true);
3519 Mock::VerifyAndClearExpectations(&dv_test);
3520 }
3521
3522 // Now for a slightly more complex variant. When we encrypt data,
3523 // we do the same verification step but monkey with the callback to
3524 // link ourselves to an encrypt step afterward.
3525 {
3526 ResultBoolCallback passed_down_callback;
3527 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3528 kFakePublicKey,
3529 kFakeNonce,
3530 kFakeSignedData,
3531 kFakeUdn,
3532 kSSID,
3533 _,
3534 _,
3535 _))
3536 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3537
3538 Error error(Error::kOperationInitiated);
3539 ResultStringCallback cb = Bind(
3540 &DestinationVerificationTest::ResultStringCallbackStub,
3541 dv_test.AsWeakPtr());
3542 manager()->VerifyAndEncryptData(kFakeCertificate,
3543 kFakePublicKey,
3544 kFakeNonce,
3545 kFakeSignedData,
3546 kFakeUdn,
3547 kFakeData,
3548 cb,
3549 &error);
3550 ASSERT_TRUE(error.IsOngoing());
3551 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3552 // Now, if we call that passed down callback, we should see encrypt being
3553 // called.
3554 ResultStringCallback second_passed_down_callback;
3555 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3556 kFakeData,
3557 _,
3558 _))
3559 .Times(1)
3560 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3561 Return(true)));
3562 Error e;
3563 passed_down_callback.Run(e, true);
3564 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3565 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3566 // And if we call the second passed down callback, we should see the
3567 // original function we passed down to VerifyDestination getting called.
3568 e.Reset();
3569 second_passed_down_callback.Run(e, "");
3570 Mock::VerifyAndClearExpectations(&dv_test);
3571 }
3572
3573 // If verification fails on the way to trying to encrypt, we should ditch
3574 // without calling encrypt at all.
3575 {
3576 ResultBoolCallback passed_down_callback;
3577 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3578 kFakePublicKey,
3579 kFakeNonce,
3580 kFakeSignedData,
3581 kFakeUdn,
3582 kSSID,
3583 _,
3584 _,
3585 _))
3586 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3587
3588 Error error(Error::kOperationInitiated);
3589 ResultStringCallback cb = Bind(
3590 &DestinationVerificationTest::ResultStringCallbackStub,
3591 dv_test.AsWeakPtr());
3592 manager()->VerifyAndEncryptData(kFakeCertificate,
3593 kFakePublicKey,
3594 kFakeNonce,
3595 kFakeSignedData,
3596 kFakeUdn,
3597 kFakeData,
3598 cb,
3599 &error);
3600 ASSERT_TRUE(error.IsOngoing());
3601 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3602 Error e(Error::kOperationFailed);
3603 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3604 // Although we're ditching, this callback is what cleans up the pending
3605 // DBus call.
3606 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3607 passed_down_callback.Run(e, false);
3608 Mock::VerifyAndClearExpectations(&dv_test);
3609 }
3610}
3611
Paul Stewartd2e1c362013-03-03 19:06:07 -08003612TEST_F(ManagerTest, IsProfileBefore) {
3613 scoped_refptr<MockProfile> profile0(
3614 new NiceMock<MockProfile>(
3615 control_interface(), metrics(), manager(), ""));
3616 scoped_refptr<MockProfile> profile1(
3617 new NiceMock<MockProfile>(
3618 control_interface(), metrics(), manager(), ""));
3619
3620 AdoptProfile(manager(), profile0);
3621 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3622 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3623 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3624
3625 // A few abnormal cases, but it's good to track their behavior.
3626 scoped_refptr<MockProfile> profile2(
3627 new NiceMock<MockProfile>(
3628 control_interface(), metrics(), manager(), ""));
3629 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3630 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3631 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3632 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3633}
3634
Chris Masone9be4a9d2011-05-16 15:44:09 -07003635} // namespace shill