blob: d14fd1a27b8acfdba508f32775ff221261ad0efc [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 Stewartd2e1c362013-03-03 19:06:07 -0800220 scoped_refptr<MockProfile> AddNamedMockProfileToManager(
221 Manager *manager, const string &name) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700222 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800223 new MockProfile(control_interface(), metrics(), manager, ""));
Paul Stewartd2e1c362013-03-03 19:06:07 -0800224 EXPECT_CALL(*profile, GetRpcIdentifier()).WillRepeatedly(Return(name));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200225 EXPECT_CALL(*profile, UpdateDevice(_)).WillRepeatedly(Return(false));
Paul Stewartcb3eb892012-06-07 14:24:46 -0700226 AdoptProfile(manager, profile);
Paul Stewartd2e1c362013-03-03 19:06:07 -0800227 return profile;
228 }
229
230 void AddMockProfileToManager(Manager *manager) {
231 AddNamedMockProfileToManager(manager, "/");
Paul Stewartcb3eb892012-06-07 14:24:46 -0700232 }
233
Paul Stewartdfa46052012-06-26 09:44:14 -0700234 void CompleteServiceSort() {
235 EXPECT_FALSE(manager()->sort_services_task_.IsCancelled());
236 dispatcher()->DispatchPendingEvents();
237 EXPECT_TRUE(manager()->sort_services_task_.IsCancelled());
238 }
239
Paul Stewart49739c02012-08-08 17:24:03 -0700240 RpcIdentifier GetDefaultServiceRpcIdentifier() {
241 return manager()->GetDefaultServiceRpcIdentifier(NULL);
242 }
243
Paul Stewart4d5efb72012-09-17 12:24:34 -0700244 void SetResolver(Resolver *resolver) {
245 manager()->resolver_ = resolver;
246 }
247
248 void SetIgnoredDNSSearchPaths(const string &search_paths) {
249 manager()->SetIgnoredDNSSearchPaths(search_paths, NULL);
250 }
251
252 const string &GetIgnoredDNSSearchPaths() {
253 return manager()->props_.ignored_dns_search_paths;
254 }
255
Paul Stewartd2e1c362013-03-03 19:06:07 -0800256 WiFiServiceRefPtr ReleaseTempMockService() {
257 // Take a reference to hold during this function.
258 WiFiServiceRefPtr temp_service = temp_mock_service_;
259 temp_mock_service_ = NULL;
260 return temp_service;
261 }
262
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700263 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000264 typedef scoped_refptr<MockService> MockServiceRefPtr;
265
Darin Petkova5e07ef2012-07-09 14:27:57 +0200266 class ServiceWatcher : public base::SupportsWeakPtr<ServiceWatcher> {
267 public:
268 ServiceWatcher() {}
269 virtual ~ServiceWatcher() {}
270
271 MOCK_METHOD1(OnDefaultServiceChanged, void(const ServiceRefPtr &service));
272
273 private:
274 DISALLOW_COPY_AND_ASSIGN(ServiceWatcher);
275 };
276
Darin Petkovca621542012-07-25 14:25:56 +0200277 class TestProxyFactory : public ProxyFactory {
278 public:
279 TestProxyFactory() {}
280
281 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
282 PowerManagerProxyDelegate */*delegate*/) {
283 return NULL;
284 }
285
286 private:
287 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
288 };
289
Darin Petkov3ec55342012-09-28 14:04:44 +0200290 class TerminationActionTest :
291 public base::SupportsWeakPtr<TerminationActionTest> {
292 public:
293 static const char kActionName[];
294
295 TerminationActionTest() : manager_(NULL) {}
296 virtual ~TerminationActionTest() {}
297
298 MOCK_METHOD1(Done, void(const Error &error));
299
300 void Action() {
301 manager_->TerminationActionComplete("action");
302 }
303
304 void set_manager(Manager *manager) { manager_ = manager; }
305
306 private:
307 Manager *manager_;
308 DISALLOW_COPY_AND_ASSIGN(TerminationActionTest);
309 };
310
Christopher Wiley1057cd72013-02-28 15:21:29 -0800311 class DestinationVerificationTest :
312 public base::SupportsWeakPtr<DestinationVerificationTest> {
313 public:
314 DestinationVerificationTest() {}
315 virtual ~DestinationVerificationTest() {}
316
317 MOCK_METHOD2(ResultBoolCallbackStub, void(const Error &result, bool flag));
318 MOCK_METHOD2(ResultStringCallbackStub, void(const Error &result,
319 const string &value));
320 private:
321 DISALLOW_COPY_AND_ASSIGN(DestinationVerificationTest);
322 };
323
Darin Petkovca621542012-07-25 14:25:56 +0200324 void SetPowerState(PowerManagerProxyDelegate::SuspendState state) {
325 power_manager_->power_state_ = state;
326 }
327
328 void SetPowerManager() {
329 manager()->set_power_manager(power_manager_.release());
330 }
331
Darin Petkov3ec55342012-09-28 14:04:44 +0200332 HookTable *GetTerminationActions() {
333 return &manager()->termination_actions_;
334 }
335
Darin Petkovca621542012-07-25 14:25:56 +0200336 void OnPowerStateChanged(PowerManagerProxyDelegate::SuspendState state) {
337 manager()->OnPowerStateChanged(state);
338 }
339
Daniel Erat0818cca2012-12-14 10:16:21 -0800340 void OnSuspendImminent(int suspend_id) {
341 manager()->OnSuspendImminent(suspend_id);
Darin Petkov3ec55342012-09-28 14:04:44 +0200342 }
343
Daniel Erat0818cca2012-12-14 10:16:21 -0800344 void OnSuspendActionsComplete(int suspend_id, const Error &error) {
345 manager()->OnSuspendActionsComplete(suspend_id, error);
Darin Petkov3ec55342012-09-28 14:04:44 +0200346 }
347
Paul Stewartbfb82552012-10-24 16:48:48 -0700348 vector<string> EnumerateAvailableServices() {
349 return manager()->EnumerateAvailableServices(NULL);
350 }
351
352 vector<string> EnumerateWatchedServices() {
353 return manager()->EnumerateWatchedServices(NULL);
354 }
355
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000356 MockServiceRefPtr MakeAutoConnectableService() {
357 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
358 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800359 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000360 manager());
361 service->MakeFavorite();
362 service->set_connectable(true);
363 return service;
364 }
365
Darin Petkovca621542012-07-25 14:25:56 +0200366 TestProxyFactory proxy_factory_;
367 scoped_ptr<MockPowerManager> power_manager_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700368 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800369 scoped_ptr<MockDeviceInfo> device_info_;
370
Paul Stewartd2e1c362013-03-03 19:06:07 -0800371 // This service is held for the manager, and given ownership in a mock
372 // function. This ensures that when the Manager takes ownership, there
373 // is only one reference left.
374 scoped_refptr<MockWiFiService> temp_mock_service_;
375
Paul Stewart3c504012013-01-17 17:49:58 -0800376 // These pointers are owned by the manager, and only tracked here for
377 // EXPECT*()
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800378 ManagerMockAdaptor *manager_adaptor_;
Paul Stewart3c504012013-01-17 17:49:58 -0800379 MockWiFiProvider *wifi_provider_;
Christopher Wiley1057cd72013-02-28 15:21:29 -0800380 MockCryptoUtilProxy *crypto_util_proxy_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700381};
382
Darin Petkov3ec55342012-09-28 14:04:44 +0200383const char ManagerTest::TerminationActionTest::kActionName[] = "action";
384
Paul Stewart22aa71b2011-09-16 12:15:11 -0700385bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
Paul Stewartdfa46052012-06-26 09:44:14 -0700386 if (!manager()->sort_services_task_.IsCancelled()) {
387 manager()->SortServicesTask();
388 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700389 return (svc0.get() == manager()->services_[0].get() &&
390 svc1.get() == manager()->services_[1].get());
391}
392
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700393TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700394 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
395 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700396}
397
Chris Masone9be4a9d2011-05-16 15:44:09 -0700398TEST_F(ManagerTest, DeviceRegistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700399 ON_CALL(*mock_devices_[0].get(), technology())
400 .WillByDefault(Return(Technology::kEthernet));
401 ON_CALL(*mock_devices_[1].get(), technology())
402 .WillByDefault(Return(Technology::kWifi));
403 ON_CALL(*mock_devices_[2].get(), technology())
404 .WillByDefault(Return(Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700405
Paul Stewart22aa71b2011-09-16 12:15:11 -0700406 manager()->RegisterDevice(mock_devices_[0]);
407 manager()->RegisterDevice(mock_devices_[1]);
408 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700409
Paul Stewart22aa71b2011-09-16 12:15:11 -0700410 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
411 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
412 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700413}
414
Paul Stewarta41e38d2011-11-11 07:47:29 -0800415TEST_F(ManagerTest, DeviceRegistrationAndStart) {
416 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500417 mock_devices_[0]->enabled_persistent_ = true;
418 mock_devices_[1]->enabled_persistent_ = false;
419 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800420 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500421 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800422 .Times(0);
423 manager()->RegisterDevice(mock_devices_[0]);
424 manager()->RegisterDevice(mock_devices_[1]);
425}
426
427TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
Thieu Le5133b712013-02-19 14:47:21 -0800428 MockProfile *profile =
429 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewarta41e38d2011-11-11 07:47:29 -0800430 DeviceRefPtr device_ref(mock_devices_[0].get());
431 AdoptProfile(manager(), profile); // Passes ownership.
432 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200433 EXPECT_CALL(*profile, UpdateDevice(device_ref));
Paul Stewarta41e38d2011-11-11 07:47:29 -0800434 manager()->RegisterDevice(mock_devices_[0]);
435}
436
Chris Masone9be4a9d2011-05-16 15:44:09 -0700437TEST_F(ManagerTest, DeviceDeregistration) {
Joshua Krollda798622012-06-05 12:30:48 -0700438 ON_CALL(*mock_devices_[0].get(), technology())
439 .WillByDefault(Return(Technology::kEthernet));
440 ON_CALL(*mock_devices_[1].get(), technology())
441 .WillByDefault(Return(Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700442
Gaurav Shah435de2c2011-11-17 19:01:07 -0800443 manager()->RegisterDevice(mock_devices_[0]);
444 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700445
Paul Stewart22aa71b2011-09-16 12:15:11 -0700446 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
447 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700448
Thieu Le5133b712013-02-19 14:47:21 -0800449 MockProfile *profile =
450 new MockProfile(control_interface(), metrics(), manager(), "");
Paul Stewart212d60f2012-07-12 10:59:13 -0700451 AdoptProfile(manager(), profile); // Passes ownership.
452
Eric Shienbrood9a245532012-03-07 14:20:39 -0500453 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700454 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[0])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800455 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700456 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700457
Eric Shienbrood9a245532012-03-07 14:20:39 -0500458 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Paul Stewart212d60f2012-07-12 10:59:13 -0700459 EXPECT_CALL(*profile, UpdateDevice(DeviceRefPtr(mock_devices_[1])));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800460 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700461 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700462}
463
464TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700465 // It's much easier and safer to use a real GLib for this test.
466 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700467 Manager manager(control_interface(),
468 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800469 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700470 &glib,
471 run_path(),
472 storage_path(),
473 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700474 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
475 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700476 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700477
Chris Masone9be4a9d2011-05-16 15:44:09 -0700478 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700479 new NiceMock<MockService>(control_interface(),
480 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800481 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700482 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700483 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700484 new NiceMock<MockService>(control_interface(),
485 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800486 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700487 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700488
Darin Petkov457728b2013-01-09 09:49:08 +0100489 string service1_name(mock_service->unique_name());
490 string service2_name(mock_service2->unique_name());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700491
492 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
493 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700494 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700495 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700496 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700497 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700498 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700499
Chris Masone9d779932011-08-25 16:33:41 -0700500 manager.RegisterService(mock_service);
501 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700502
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800503 Error error;
504 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700505 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700506 EXPECT_EQ(2, ids.size());
507 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
508 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700509
Chris Masone9d779932011-08-25 16:33:41 -0700510 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
511 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
512
513 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700514}
515
Chris Masone6515aab2011-10-12 16:19:09 -0700516TEST_F(ManagerTest, RegisterKnownService) {
517 // It's much easier and safer to use a real GLib for this test.
518 GLib glib;
519 Manager manager(control_interface(),
520 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800521 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700522 &glib,
523 run_path(),
524 storage_path(),
525 string());
526 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
527 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700528 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700529 {
530 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
531 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800532 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700533 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700534 ASSERT_TRUE(profile->AdoptService(service1));
535 ASSERT_TRUE(profile->ContainsService(service1));
536 } // Force destruction of service1.
537
538 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
539 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800540 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700541 &manager));
542 manager.RegisterService(service2);
543 EXPECT_EQ(service2->profile().get(), profile.get());
544 manager.Stop();
545}
546
547TEST_F(ManagerTest, RegisterUnknownService) {
548 // It's much easier and safer to use a real GLib for this test.
549 GLib glib;
550 Manager manager(control_interface(),
551 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800552 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700553 &glib,
554 run_path(),
555 storage_path(),
556 string());
557 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
558 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700559 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700560 {
561 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
562 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800563 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700564 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700565 ASSERT_TRUE(profile->AdoptService(service1));
566 ASSERT_TRUE(profile->ContainsService(service1));
567 } // Force destruction of service1.
568 scoped_refptr<MockService> mock_service2(
569 new NiceMock<MockService>(control_interface(),
570 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800571 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700572 &manager));
573 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
Darin Petkov457728b2013-01-09 09:49:08 +0100574 .WillRepeatedly(Return(mock_service2->unique_name()));
Chris Masone6515aab2011-10-12 16:19:09 -0700575 manager.RegisterService(mock_service2);
576 EXPECT_NE(mock_service2->profile().get(), profile.get());
577 manager.Stop();
578}
579
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000580TEST_F(ManagerTest, DeregisterUnregisteredService) {
581 // WiFi assumes that it can deregister a service that is not
582 // registered. (E.g. a hidden service can be deregistered when it
583 // loses its last endpoint, and again when WiFi is Stop()-ed.)
584 //
585 // So test that doing so doesn't cause a crash.
586 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
587 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800588 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000589 manager());
590 manager()->DeregisterService(service);
591}
592
Chris Masonea8a2c252011-06-27 22:16:30 -0700593TEST_F(ManagerTest, GetProperties) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700594 AddMockProfileToManager(manager());
Chris Masonea8a2c252011-06-27 22:16:30 -0700595 map<string, ::DBus::Variant> props;
596 Error error(Error::kInvalidProperty, "");
597 {
598 ::DBus::Error dbus_error;
599 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700600 manager()->mutable_store()->SetStringProperty(
601 flimflam::kCheckPortalListProperty,
602 expected,
603 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700604 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700605 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
606 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
607 expected);
608 }
609 {
610 ::DBus::Error dbus_error;
611 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700612 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
613 expected,
614 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700615 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700616 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
617 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
618 expected);
619 }
620}
621
Chris Masone3c3f6a12011-07-01 10:01:41 -0700622TEST_F(ManagerTest, GetDevicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700623 AddMockProfileToManager(manager());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800624 manager()->RegisterDevice(mock_devices_[0]);
625 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700626 {
627 map<string, ::DBus::Variant> props;
628 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700629 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700630 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
Paul Stewartcb3eb892012-06-07 14:24:46 -0700631 vector < ::DBus::Path> devices =
632 props[flimflam::kDevicesProperty].operator vector< ::DBus::Path>();
Chris Masone3c3f6a12011-07-01 10:01:41 -0700633 EXPECT_EQ(2, devices.size());
634 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700635}
636
mukesh agrawal2366eed2012-03-20 18:21:50 -0700637TEST_F(ManagerTest, GetServicesProperty) {
Paul Stewartcb3eb892012-06-07 14:24:46 -0700638 AddMockProfileToManager(manager());
mukesh agrawal2366eed2012-03-20 18:21:50 -0700639 map<string, ::DBus::Variant> props;
640 ::DBus::Error dbus_error;
641 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
642 map<string, ::DBus::Variant>::const_iterator prop =
643 props.find(flimflam::kServicesProperty);
644 ASSERT_FALSE(prop == props.end());
645 const ::DBus::Variant &variant = prop->second;
646 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
647}
648
Chris Masone6791a432011-07-12 13:23:19 -0700649TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700650 Manager manager(control_interface(),
651 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800652 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700653 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700654 run_path(),
655 storage_path(),
656 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700657 scoped_refptr<MockService> s2(new MockService(control_interface(),
658 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800659 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700660 &manager));
661 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700662 {
Chris Masone6515aab2011-10-12 16:19:09 -0700663 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700664 ProfileRefPtr profile(
Thieu Le5133b712013-02-19 14:47:21 -0800665 new Profile(control_interface(), metrics(), &manager, id, "", false));
Chris Masoneb9c00592011-10-06 13:10:39 -0700666 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700667 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700668 .WillRepeatedly(Return(true));
669 EXPECT_CALL(*storage, Flush())
670 .Times(AnyNumber())
671 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700672 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700673 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700674 }
Chris Masone6515aab2011-10-12 16:19:09 -0700675 // Create a profile that already has |s2| in it.
Thieu Le5133b712013-02-19 14:47:21 -0800676 ProfileRefPtr profile(
677 new EphemeralProfile(control_interface(), metrics(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700678 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700679
Chris Masone6515aab2011-10-12 16:19:09 -0700680 // Now, move the Service |s2| to another profile.
681 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
682 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700683
684 // Force destruction of the original Profile, to ensure that the Service
685 // is kept alive and populated with data.
686 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700687 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700688 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700689}
690
Paul Stewart7f61e522012-03-22 11:13:45 -0700691TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
692 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800693 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -0700694 const string kProfileName("profile0");
695 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
696 .WillRepeatedly(Return(kProfileName));
697 AdoptProfile(manager(), mock_profile);
698
699 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
700 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
701 EXPECT_EQ(mock_profile.get(), profile.get());
702}
703
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800704TEST_F(ManagerTest, SetProfileForService) {
705 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -0800706 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800707 string profile_name0("profile0");
708 EXPECT_CALL(*profile0, GetRpcIdentifier())
709 .WillRepeatedly(Return(profile_name0));
710 AdoptProfile(manager(), profile0);
711 scoped_refptr<MockService> service(new MockService(control_interface(),
712 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800713 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800714 manager()));
Paul Stewart649f3a42012-04-24 23:22:16 -0700715 EXPECT_FALSE(manager()->HasService(service));
716 {
717 Error error;
718 EXPECT_CALL(*profile0, AdoptService(_))
719 .WillOnce(Return(true));
720 // Expect that setting the profile of a service that does not already
721 // have one assigned does not cause a crash.
722 manager()->SetProfileForService(service, "profile0", &error);
723 EXPECT_TRUE(error.IsSuccess());
724 }
725
726 // The service should be registered as a side-effect of the profile being
727 // set for this service.
728 EXPECT_TRUE(manager()->HasService(service));
729
730 // Since we have mocked Profile::AdoptServie() above, the service's
731 // profile was not actually changed. Do so explicitly now.
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800732 service->set_profile(profile0);
733
734 {
735 Error error;
736 manager()->SetProfileForService(service, "foo", &error);
737 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700738 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800739 }
740
741 {
742 Error error;
743 manager()->SetProfileForService(service, profile_name0, &error);
744 EXPECT_EQ(Error::kInvalidArguments, error.type());
745 EXPECT_EQ("Service is already connected to this profile", error.message());
746 }
747
748 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -0800749 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800750 string profile_name1("profile1");
751 EXPECT_CALL(*profile1, GetRpcIdentifier())
752 .WillRepeatedly(Return(profile_name1));
753 AdoptProfile(manager(), profile1);
754
755 {
756 Error error;
757 EXPECT_CALL(*profile1, AdoptService(_))
758 .WillOnce(Return(true));
759 EXPECT_CALL(*profile0, AbandonService(_))
760 .WillOnce(Return(true));
761 manager()->SetProfileForService(service, profile_name1, &error);
762 EXPECT_TRUE(error.IsSuccess());
763 }
764}
765
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700766TEST_F(ManagerTest, CreateProfile) {
767 // It's much easier to use real Glib here since we want the storage
768 // side-effects.
769 GLib glib;
770 ScopedTempDir temp_dir;
771 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
772
773 Manager manager(control_interface(),
774 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800775 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700776 &glib,
777 run_path(),
778 storage_path(),
779 temp_dir.path().value());
780
781 // Invalid name should be rejected.
782 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
783
Paul Stewartd0a3b812012-03-28 22:48:22 -0700784 // A profile with invalid characters in it should similarly be rejected.
785 EXPECT_EQ(Error::kInvalidArguments,
786 TestCreateProfile(&manager, "valid_profile"));
787
788 // We should be able to create a machine profile.
789 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700790
Gary Morainb672d352012-04-25 09:19:06 -0700791 // We should succeed in creating a valid user profile. Verify the returned
792 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700793 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700794 {
795 Error error;
796 string path;
797 manager.CreateProfile(kProfile, &path, &error);
798 EXPECT_EQ(Error::kSuccess, error.type());
799 EXPECT_EQ("/profile_rpc", path);
800 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700801
802 // We should fail in creating it a second time (already exists).
803 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
804}
805
Christopher Wiley3e7635e2012-08-15 09:46:17 -0700806// We receive PopProfile when a user logs out, and it should always trigger a
807// MemoryLog Clear() call.
808TEST_F(ManagerTest, PopProfileShouldClearMemoryLog) {
809 GLib glib;
810 ScopedTempDir temp_dir;
811 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
812 Manager manager(control_interface(),
813 dispatcher(),
814 metrics(),
815 &glib,
816 run_path(),
817 storage_path(),
818 temp_dir.path().value());
819 const char kProfile0[] = "~user/profile0";
820 const char kPurgedMessage[] = "This message should be purged";
821 // Create a profile and push it on the stack, leave one uncreated
822 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
823 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
824
825 // Popping a profile which isn't on top should still clear the log.
826 LOG(INFO) << kPurgedMessage;
827 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
828 kPurgedMessage));
829 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, "~user/profile1"));
830 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
831 kPurgedMessage));
832
833 // Popping an invalid profile name should do the same thing.
834 LOG(INFO) << kPurgedMessage;
835 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
836 kPurgedMessage));
837 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
838 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
839 kPurgedMessage));
840
841 // Successful pops also purge the message log.
842 LOG(INFO) << kPurgedMessage;
843 EXPECT_TRUE(MemoryLog::GetInstance()->TestContainsMessageWithText(
844 kPurgedMessage));
845 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile0));
846 EXPECT_FALSE(MemoryLog::GetInstance()->TestContainsMessageWithText(
847 kPurgedMessage));
848}
849
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700850TEST_F(ManagerTest, PushPopProfile) {
851 // It's much easier to use real Glib in creating a Manager for this
852 // test here since we want the storage side-effects.
853 GLib glib;
854 ScopedTempDir temp_dir;
855 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
856 Manager manager(control_interface(),
857 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800858 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700859 &glib,
860 run_path(),
861 storage_path(),
862 temp_dir.path().value());
863
864 // Pushing an invalid profile should fail.
865 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
866
Paul Stewartd0a3b812012-03-28 22:48:22 -0700867 // Pushing a default profile that does not exist should fail.
868 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700869
870 const char kProfile0[] = "~user/profile0";
871 const char kProfile1[] = "~user/profile1";
872
873 // Create a couple of profiles.
874 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
875 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
876
877 // Push these profiles on the stack.
878 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
879 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
880
881 // Pushing a profile a second time should fail.
882 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
883 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
884
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800885 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700886 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800887 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700888
889 // Make sure a profile name that doesn't exist fails.
890 const char kProfile2Id[] = "profile2";
891 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
892 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
893
894 // Create a new service, with a specific storage name.
895 scoped_refptr<MockService> service(
896 new NiceMock<MockService>(control_interface(),
897 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800898 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700899 &manager));
900 const char kServiceName[] = "service_storage_name";
901 EXPECT_CALL(*service.get(), GetStorageIdentifier())
902 .WillRepeatedly(Return(kServiceName));
903 EXPECT_CALL(*service.get(), Load(_))
904 .WillRepeatedly(Return(true));
905
906 // Add this service to the manager -- it should end up in the ephemeral
907 // profile.
908 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800909 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700910
911 // Create storage for a profile that contains the service storage name.
912 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
913 kServiceName));
914
915 // When we push the profile, the service should move away from the
916 // ephemeral profile to this new profile since it has an entry for
917 // this service.
918 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800919 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700920 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
921
922 // Insert another profile that should supersede ownership of the service.
923 const char kProfile3Id[] = "profile3";
924 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
925 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
926 kServiceName));
927 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
928 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
929
930 // Popping an invalid profile name should fail.
931 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
932
933 // Popping an profile that is not at the top of the stack should fail.
934 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
935
936 // Popping the top profile should succeed.
937 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
938
939 // Moreover the service should have switched profiles to profile 2.
940 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
941
942 // Popping the top profile should succeed.
943 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
944
945 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800946 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700947
948 // Pop the remaining two services off the stack.
949 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
950 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
951
952 // Next pop should fail with "stack is empty".
953 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700954
955 const char kMachineProfile0[] = "machineprofile0";
956 const char kMachineProfile1[] = "machineprofile1";
957 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
958 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
959
960 // Should be able to push a machine profile.
961 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
962
963 // Should be able to push a user profile atop a machine profile.
964 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
965
966 // Pushing a system-wide profile on top of a user profile should fail.
967 EXPECT_EQ(Error::kInvalidArguments,
968 TestPushProfile(&manager, kMachineProfile1));
969
970 // However if we pop the user profile, we should be able stack another
971 // machine profile on.
972 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
973 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart307c2502013-03-23 12:32:10 -0700974
975 // Add two user profiles to the top of the stack.
976 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
977 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
978 vector<ProfileRefPtr> &profiles = GetProfiles(&manager);
979 EXPECT_EQ(4, profiles.size());
980
981 // PopAllUserProfiles should remove both user profiles, leaving the two
982 // machine profiles.
983 EXPECT_EQ(Error::kSuccess, TestPopAllUserProfiles(&manager));
984 EXPECT_EQ(2, profiles.size());
985 EXPECT_TRUE(profiles[0]->GetUser().empty());
986 EXPECT_TRUE(profiles[1]->GetUser().empty());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700987}
988
Paul Stewarte73d05c2012-03-29 16:26:05 -0700989TEST_F(ManagerTest, RemoveProfile) {
990 // It's much easier to use real Glib in creating a Manager for this
991 // test here since we want the storage side-effects.
992 GLib glib;
993 ScopedTempDir temp_dir;
994 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
995 Manager manager(control_interface(),
996 dispatcher(),
997 metrics(),
998 &glib,
999 run_path(),
1000 storage_path(),
1001 temp_dir.path().value());
1002
1003 const char kProfile0[] = "profile0";
1004 FilePath profile_path(
1005 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1006
1007 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1008 ASSERT_TRUE(file_util::PathExists(profile_path));
1009
1010 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1011
1012 // Remove should fail since the profile is still on the stack.
1013 {
1014 Error error;
1015 manager.RemoveProfile(kProfile0, &error);
1016 EXPECT_EQ(Error::kInvalidArguments, error.type());
1017 }
1018
1019 // Profile path should still exist.
1020 EXPECT_TRUE(file_util::PathExists(profile_path));
1021
1022 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
1023
1024 // This should succeed now that the profile is off the stack.
1025 {
1026 Error error;
1027 manager.RemoveProfile(kProfile0, &error);
1028 EXPECT_EQ(Error::kSuccess, error.type());
1029 }
1030
1031 // Profile path should no longer exist.
1032 EXPECT_FALSE(file_util::PathExists(profile_path));
1033
1034 // Another remove succeeds, due to a foible in file_util::Delete --
1035 // it is not an error to delete a file that does not exist.
1036 {
1037 Error error;
1038 manager.RemoveProfile(kProfile0, &error);
1039 EXPECT_EQ(Error::kSuccess, error.type());
1040 }
1041
1042 // Let's create an error case that will "work". Create a non-empty
1043 // directory in the place of the profile pathname.
1044 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
1045 {
1046 Error error;
1047 manager.RemoveProfile(kProfile0, &error);
1048 EXPECT_EQ(Error::kOperationFailed, error.type());
1049 }
1050}
1051
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001052TEST_F(ManagerTest, CreateDuplicateProfileWithMissingKeyfile) {
1053 // It's much easier to use real Glib in creating a Manager for this
1054 // test here since we want the storage side-effects.
1055 GLib glib;
1056 ScopedTempDir temp_dir;
1057 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1058 Manager manager(control_interface(),
1059 dispatcher(),
1060 metrics(),
1061 &glib,
1062 run_path(),
1063 storage_path(),
1064 temp_dir.path().value());
1065
1066 const char kProfile0[] = "profile0";
1067 FilePath profile_path(
1068 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
1069
1070 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
1071 ASSERT_TRUE(file_util::PathExists(profile_path));
1072 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
1073
1074 // Ensure that even if the backing filestore is removed, we still can't
1075 // create a profile twice.
1076 ASSERT_TRUE(file_util::Delete(profile_path, false));
1077 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile0));
1078}
1079
Paul Stewart75225512012-01-26 22:51:33 -08001080// Use this matcher instead of passing RefPtrs directly into the arguments
1081// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
1082// system teardown.
1083MATCHER_P(IsRefPtrTo, ref_address, "") {
1084 return arg.get() == ref_address;
1085}
1086
1087TEST_F(ManagerTest, HandleProfileEntryDeletion) {
1088 MockServiceRefPtr s_not_in_profile(
1089 new NiceMock<MockService>(control_interface(),
1090 dispatcher(),
1091 metrics(),
1092 manager()));
1093 MockServiceRefPtr s_not_in_group(
1094 new NiceMock<MockService>(control_interface(),
1095 dispatcher(),
1096 metrics(),
1097 manager()));
1098 MockServiceRefPtr s_configure_fail(
1099 new NiceMock<MockService>(control_interface(),
1100 dispatcher(),
1101 metrics(),
1102 manager()));
1103 MockServiceRefPtr s_configure_succeed(
1104 new NiceMock<MockService>(control_interface(),
1105 dispatcher(),
1106 metrics(),
1107 manager()));
1108
1109 string entry_name("entry_name");
1110 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
1111 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
1112 .WillRepeatedly(Return("not_entry_name"));
1113 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
1114 .WillRepeatedly(Return(entry_name));
1115 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
1116 .WillRepeatedly(Return(entry_name));
1117
1118 manager()->RegisterService(s_not_in_profile);
1119 manager()->RegisterService(s_not_in_group);
1120 manager()->RegisterService(s_configure_fail);
1121 manager()->RegisterService(s_configure_succeed);
1122
1123 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001124 new StrictMock<MockProfile>(
1125 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001126 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001127 new StrictMock<MockProfile>(
1128 control_interface(), metrics(), manager(), ""));
Paul Stewart75225512012-01-26 22:51:33 -08001129
1130 s_not_in_group->set_profile(profile1);
1131 s_configure_fail->set_profile(profile1);
1132 s_configure_succeed->set_profile(profile1);
1133
1134 AdoptProfile(manager(), profile0);
1135 AdoptProfile(manager(), profile1);
1136
1137 // No services are a member of this profile.
1138 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
1139
1140 // No services that are members of this profile have this entry name.
1141 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
1142
1143 // Only services that are members of the profile and group will be abandoned.
1144 EXPECT_CALL(*profile1.get(),
1145 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1146 EXPECT_CALL(*profile1.get(),
1147 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1148 EXPECT_CALL(*profile1.get(),
1149 AbandonService(IsRefPtrTo(s_configure_fail.get())))
1150 .WillOnce(Return(true));
1151 EXPECT_CALL(*profile1.get(),
1152 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
1153 .WillOnce(Return(true));
1154
1155 // Never allow services to re-join profile1.
1156 EXPECT_CALL(*profile1.get(), ConfigureService(_))
1157 .WillRepeatedly(Return(false));
1158
1159 // Only allow one of the members of the profile and group to successfully
1160 // join profile0.
1161 EXPECT_CALL(*profile0.get(),
1162 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
1163 EXPECT_CALL(*profile0.get(),
1164 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
1165 EXPECT_CALL(*profile0.get(),
1166 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
1167 .WillOnce(Return(false));
1168 EXPECT_CALL(*profile0.get(),
1169 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
1170 .WillOnce(Return(true));
1171
1172 // Expect the failed-to-configure service to have Unload() called on it.
1173 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
1174 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
1175 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
1176 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
1177
1178 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
1179
1180 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
1181 EXPECT_EQ(profile1, s_not_in_group->profile());
1182 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
1183
1184 // Since we are using a MockProfile, the profile does not actually change,
1185 // since ConfigureService was not actually called on the service.
1186 EXPECT_EQ(profile1, s_configure_succeed->profile());
1187}
1188
Paul Stewart65512e12012-03-26 18:01:08 -07001189TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
1190 MockServiceRefPtr s_will_remove0(
1191 new NiceMock<MockService>(control_interface(),
1192 dispatcher(),
1193 metrics(),
1194 manager()));
1195 MockServiceRefPtr s_will_remove1(
1196 new NiceMock<MockService>(control_interface(),
1197 dispatcher(),
1198 metrics(),
1199 manager()));
1200 MockServiceRefPtr s_will_not_remove0(
1201 new NiceMock<MockService>(control_interface(),
1202 dispatcher(),
1203 metrics(),
1204 manager()));
1205 MockServiceRefPtr s_will_not_remove1(
1206 new NiceMock<MockService>(control_interface(),
1207 dispatcher(),
1208 metrics(),
1209 manager()));
1210
1211 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1212 .Times(4); // Once for each registration.
1213
1214 string entry_name("entry_name");
1215 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
1216 .WillRepeatedly(Return(entry_name));
1217 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
1218 .WillRepeatedly(Return(entry_name));
1219 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
1220 .WillRepeatedly(Return(entry_name));
1221 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
1222 .WillRepeatedly(Return(entry_name));
1223
1224 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001225 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001226 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001227 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001228 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001229 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001230 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001231 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001232
1233 // One for each service added above.
1234 ASSERT_EQ(4, manager()->services_.size());
1235
1236 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001237 new StrictMock<MockProfile>(
1238 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001239
1240 s_will_remove0->set_profile(profile);
1241 s_will_remove1->set_profile(profile);
1242 s_will_not_remove0->set_profile(profile);
1243 s_will_not_remove1->set_profile(profile);
1244
1245 AdoptProfile(manager(), profile);
1246
1247 // Deny any of the services re-entry to the profile.
1248 EXPECT_CALL(*profile, ConfigureService(_))
1249 .WillRepeatedly(Return(false));
1250
1251 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
1252 .WillOnce(Return(true));
1253 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
1254 .WillOnce(Return(true));
1255 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
1256 .WillOnce(Return(true));
1257 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
1258 .WillOnce(Return(true));
1259
1260 EXPECT_CALL(*s_will_remove0, Unload())
1261 .WillOnce(Return(true));
1262 EXPECT_CALL(*s_will_remove1, Unload())
1263 .WillOnce(Return(true));
1264 EXPECT_CALL(*s_will_not_remove0, Unload())
1265 .WillOnce(Return(false));
1266 EXPECT_CALL(*s_will_not_remove1, Unload())
1267 .WillOnce(Return(false));
1268
1269
1270 // This will cause all the profiles to be unloaded.
1271 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
1272
1273 // 2 of the 4 services added above should have been unregistered and
1274 // removed, leaving 2.
1275 EXPECT_EQ(2, manager()->services_.size());
1276 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1277 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1278}
1279
1280TEST_F(ManagerTest, PopProfileWithUnload) {
1281 MockServiceRefPtr s_will_remove0(
1282 new NiceMock<MockService>(control_interface(),
1283 dispatcher(),
1284 metrics(),
1285 manager()));
1286 MockServiceRefPtr s_will_remove1(
1287 new NiceMock<MockService>(control_interface(),
1288 dispatcher(),
1289 metrics(),
1290 manager()));
1291 MockServiceRefPtr s_will_not_remove0(
1292 new NiceMock<MockService>(control_interface(),
1293 dispatcher(),
1294 metrics(),
1295 manager()));
1296 MockServiceRefPtr s_will_not_remove1(
1297 new NiceMock<MockService>(control_interface(),
1298 dispatcher(),
1299 metrics(),
1300 manager()));
1301
1302 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1303 .Times(5); // Once for each registration, and one after profile pop.
1304
1305 manager()->RegisterService(s_will_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001306 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001307 manager()->RegisterService(s_will_not_remove0);
Paul Stewartdfa46052012-06-26 09:44:14 -07001308 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001309 manager()->RegisterService(s_will_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001310 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001311 manager()->RegisterService(s_will_not_remove1);
Paul Stewartdfa46052012-06-26 09:44:14 -07001312 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001313
1314 // One for each service added above.
1315 ASSERT_EQ(4, manager()->services_.size());
1316
1317 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001318 new StrictMock<MockProfile>(
1319 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001320 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001321 new StrictMock<MockProfile>(
1322 control_interface(), metrics(), manager(), ""));
Paul Stewart65512e12012-03-26 18:01:08 -07001323
1324 s_will_remove0->set_profile(profile1);
1325 s_will_remove1->set_profile(profile1);
1326 s_will_not_remove0->set_profile(profile1);
1327 s_will_not_remove1->set_profile(profile1);
1328
1329 AdoptProfile(manager(), profile0);
1330 AdoptProfile(manager(), profile1);
1331
1332 // Deny any of the services entry to profile0, so they will all be unloaded.
1333 EXPECT_CALL(*profile0, ConfigureService(_))
1334 .WillRepeatedly(Return(false));
1335
1336 EXPECT_CALL(*s_will_remove0, Unload())
1337 .WillOnce(Return(true));
1338 EXPECT_CALL(*s_will_remove1, Unload())
1339 .WillOnce(Return(true));
1340 EXPECT_CALL(*s_will_not_remove0, Unload())
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001341 .WillRepeatedly(Return(false));
Paul Stewart65512e12012-03-26 18:01:08 -07001342 EXPECT_CALL(*s_will_not_remove1, Unload())
1343 .WillOnce(Return(false));
1344
Philipp Neubeck79173602012-11-13 21:10:09 +01001345 // Ignore calls to Profile::GetRpcIdentifier because of emitted changes of the
1346 // profile list.
1347 EXPECT_CALL(*profile0, GetRpcIdentifier()).Times(AnyNumber());
1348 EXPECT_CALL(*profile1, GetRpcIdentifier()).Times(AnyNumber());
1349
Paul Stewart65512e12012-03-26 18:01:08 -07001350 // This will pop profile1, which should cause all our profiles to unload.
1351 manager()->PopProfileInternal();
Paul Stewartdfa46052012-06-26 09:44:14 -07001352 CompleteServiceSort();
Paul Stewart65512e12012-03-26 18:01:08 -07001353
1354 // 2 of the 4 services added above should have been unregistered and
1355 // removed, leaving 2.
1356 EXPECT_EQ(2, manager()->services_.size());
1357 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1358 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
Paul Stewartfc9a1da2012-06-27 15:54:52 -07001359
1360 // Expect the unloaded services to lose their profile reference.
1361 EXPECT_FALSE(s_will_remove0->profile());
1362 EXPECT_FALSE(s_will_remove1->profile());
1363
1364 // If we explicitly deregister a service, the effect should be the same
1365 // with respect to the profile reference.
1366 ASSERT_TRUE(s_will_not_remove0->profile());
1367 manager()->DeregisterService(s_will_not_remove0);
1368 EXPECT_FALSE(s_will_not_remove0->profile());
Paul Stewart65512e12012-03-26 18:01:08 -07001369}
1370
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001371TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001372 {
1373 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001374 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1375 flimflam::kOfflineModeProperty,
1376 PropertyStoreTest::kBoolV,
1377 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001378 }
1379 {
1380 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001381 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1382 flimflam::kCountryProperty,
1383 PropertyStoreTest::kStringV,
1384 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001385 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001386 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001387 {
1388 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001389 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1390 flimflam::kCountryProperty,
1391 PropertyStoreTest::kBoolV,
1392 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001393 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001394 }
1395 {
1396 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001397 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1398 flimflam::kOfflineModeProperty,
1399 PropertyStoreTest::kStringV,
1400 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001401 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001402 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001403 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001404 {
1405 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001406 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001407 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001408 flimflam::kEnabledTechnologiesProperty,
1409 PropertyStoreTest::kStringsV,
1410 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001411 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001412 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001413}
1414
mukesh agrawal32399322011-09-01 10:53:43 -07001415TEST_F(ManagerTest, RequestScan) {
1416 {
1417 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001418 manager()->RegisterDevice(mock_devices_[0].get());
1419 manager()->RegisterDevice(mock_devices_[1].get());
Joshua Krollda798622012-06-05 12:30:48 -07001420 EXPECT_CALL(*mock_devices_[0], technology())
1421 .WillRepeatedly(Return(Technology::kWifi));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001422 EXPECT_CALL(*mock_devices_[0], Scan(_));
Joshua Krollda798622012-06-05 12:30:48 -07001423 EXPECT_CALL(*mock_devices_[1], technology())
1424 .WillRepeatedly(Return(Technology::kUnknown));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001425 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001426 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001427 }
1428
1429 {
1430 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001431 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001432 EXPECT_EQ(Error::kInvalidArguments, error.type());
1433 }
1434}
1435
Darin Petkovb65c2452012-02-23 15:17:06 +01001436TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001437 KeyValueStore args;
1438 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001439 manager()->GetService(args, &e);
1440 EXPECT_EQ(Error::kInvalidArguments, e.type());
1441 EXPECT_EQ("must specify service type", e.message());
1442}
1443
1444TEST_F(ManagerTest, GetServiceUnknownType) {
1445 KeyValueStore args;
1446 Error e;
1447 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1448 manager()->GetService(args, &e);
1449 EXPECT_EQ(Error::kNotSupported, e.type());
1450 EXPECT_EQ("service type is unsupported", e.message());
1451}
1452
Darin Petkovb65c2452012-02-23 15:17:06 +01001453TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001454 KeyValueStore args;
1455 Error e;
1456 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001457 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
Paul Stewart3c504012013-01-17 17:49:58 -08001458 EXPECT_CALL(*wifi_provider_, GetService(_, _))
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001459 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001460 manager()->GetService(args, &e);
1461 EXPECT_TRUE(e.IsSuccess());
1462}
1463
Darin Petkov33af05c2012-02-28 10:10:30 +01001464TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1465 KeyValueStore args;
1466 Error e;
1467 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001468 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001469 new StrictMock<MockProfile>(
1470 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001471 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001472 ServiceRefPtr service = manager()->GetService(args, &e);
1473 EXPECT_EQ(Error::kNotSupported, e.type());
1474 EXPECT_FALSE(service);
1475}
1476
Darin Petkovb65c2452012-02-23 15:17:06 +01001477TEST_F(ManagerTest, GetServiceVPN) {
1478 KeyValueStore args;
1479 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001480 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001481 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001482 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1483 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001484 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001485 new StrictMock<MockProfile>(
1486 control_interface(), metrics(), manager(), ""));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001487 AdoptProfile(manager(), profile);
Darin Petkovc3505a52013-03-18 15:13:29 +01001488
1489#if defined(DISABLE_VPN)
1490
1491 ServiceRefPtr service = manager()->GetService(args, &e);
1492 EXPECT_EQ(Error::kNotSupported, e.type());
1493 EXPECT_FALSE(service);
1494
1495#else
1496
Paul Stewart7f5ad572012-06-04 15:18:54 -07001497 ServiceRefPtr updated_service;
1498 EXPECT_CALL(*profile, UpdateService(_))
1499 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1500 ServiceRefPtr configured_service;
Paul Stewart2c575d22012-12-07 12:28:57 -08001501 EXPECT_CALL(*profile, LoadService(_))
1502 .WillOnce(Return(false));
Paul Stewart7f5ad572012-06-04 15:18:54 -07001503 EXPECT_CALL(*profile, ConfigureService(_))
1504 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001505 ServiceRefPtr service = manager()->GetService(args, &e);
1506 EXPECT_TRUE(e.IsSuccess());
1507 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001508 EXPECT_EQ(service, updated_service);
1509 EXPECT_EQ(service, configured_service);
Darin Petkovc3505a52013-03-18 15:13:29 +01001510
1511#endif // DISABLE_VPN
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001512}
1513
Darin Petkovc63dcf02012-05-24 11:51:43 +02001514TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1515 KeyValueStore args;
1516 Error e;
1517 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1518 ServiceRefPtr service = manager()->GetService(args, &e);
1519 EXPECT_EQ(Error::kInvalidArguments, e.type());
1520 EXPECT_EQ("Missing WiMAX network id.", e.message());
1521 EXPECT_FALSE(service);
1522}
1523
Darin Petkovd1cd7972012-05-22 15:26:15 +02001524TEST_F(ManagerTest, GetServiceWiMax) {
1525 KeyValueStore args;
1526 Error e;
1527 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001528 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1529 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1530 ServiceRefPtr service = manager()->GetService(args, &e);
1531 EXPECT_TRUE(e.IsSuccess());
1532 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001533}
1534
Paul Stewart7f61e522012-03-22 11:13:45 -07001535TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1536 // Manager calls ActiveProfile() so we need at least one profile installed.
1537 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001538 new NiceMock<MockProfile>(
1539 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001540 AdoptProfile(manager(), profile);
1541
1542 KeyValueStore args;
1543 args.SetString(flimflam::kProfileProperty, "xxx");
1544 Error error;
1545 manager()->ConfigureService(args, &error);
1546 EXPECT_EQ(Error::kInvalidArguments, error.type());
1547 EXPECT_EQ("Invalid profile name xxx", error.message());
1548}
1549
1550TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1551 // Manager calls ActiveProfile() so we need at least one profile installed.
1552 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001553 new NiceMock<MockProfile>(
1554 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001555 AdoptProfile(manager(), profile);
1556
1557 KeyValueStore args;
1558 Error error;
1559 manager()->ConfigureService(args, &error);
1560 EXPECT_EQ(Error::kInvalidArguments, error.type());
1561 EXPECT_EQ("must specify service type", error.message());
1562}
1563
1564// A registered service in the ephemeral profile should be moved to the
1565// active profile as a part of configuration if no profile was explicitly
1566// specified.
1567TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1568 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001569 new NiceMock<MockProfile>(
1570 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001571
1572 AdoptProfile(manager(), profile); // This is now the active profile.
1573
Paul Stewartd2e1c362013-03-03 19:06:07 -08001574 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001575 scoped_refptr<MockWiFiService> service(
1576 new NiceMock<MockWiFiService>(control_interface(),
1577 dispatcher(),
1578 metrics(),
1579 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001580 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001581 ssid,
1582 "",
1583 "",
1584 false));
1585
1586 manager()->RegisterService(service);
1587 service->set_profile(GetEphemeralProfile(manager()));
1588
Paul Stewart3c504012013-01-17 17:49:58 -08001589 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001590 .WillOnce(Return(service));
1591 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1592 .WillOnce(Return(true));
1593 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1594 .WillOnce(Return(true));
1595
1596 KeyValueStore args;
1597 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1598 Error error;
1599 manager()->ConfigureService(args, &error);
1600 EXPECT_TRUE(error.IsSuccess());
1601}
1602
Paul Stewart2c575d22012-12-07 12:28:57 -08001603// If we configure a service that was already registered and explicitly
Paul Stewart7f61e522012-03-22 11:13:45 -07001604// specify a profile, it should be moved from the profile it was previously
1605// in to the specified profile if one was requested.
1606TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1607 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001608 new NiceMock<MockProfile>(
1609 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001610 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001611 new NiceMock<MockProfile>(
1612 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001613
1614 const string kProfileName0 = "profile0";
1615 const string kProfileName1 = "profile1";
1616
1617 EXPECT_CALL(*profile0, GetRpcIdentifier())
1618 .WillRepeatedly(Return(kProfileName0));
1619 EXPECT_CALL(*profile1, GetRpcIdentifier())
1620 .WillRepeatedly(Return(kProfileName1));
1621
1622 AdoptProfile(manager(), profile0);
1623 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1624
Paul Stewartd2e1c362013-03-03 19:06:07 -08001625 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001626 scoped_refptr<MockWiFiService> service(
1627 new NiceMock<MockWiFiService>(control_interface(),
1628 dispatcher(),
1629 metrics(),
1630 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001631 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001632 ssid,
1633 "",
1634 "",
1635 false));
1636
1637 manager()->RegisterService(service);
1638 service->set_profile(profile1);
1639
Paul Stewart3c504012013-01-17 17:49:58 -08001640 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001641 .WillOnce(Return(service));
Paul Stewart2c575d22012-12-07 12:28:57 -08001642 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1643 .WillOnce(Return(true));
Paul Stewart7f61e522012-03-22 11:13:45 -07001644 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1645 .WillOnce(Return(true));
1646 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1647 .WillOnce(Return(true));
1648 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1649 .WillOnce(Return(true));
1650
1651 KeyValueStore args;
1652 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1653 args.SetString(flimflam::kProfileProperty, kProfileName0);
1654 Error error;
1655 manager()->ConfigureService(args, &error);
1656 EXPECT_TRUE(error.IsSuccess());
1657 service->set_profile(NULL); // Breaks refcounting loop.
1658}
1659
Paul Stewart2c575d22012-12-07 12:28:57 -08001660// If we configure a service that is already a member of the specified
1661// profile, the Manager should not call LoadService or AdoptService again
1662// on this service.
1663TEST_F(ManagerTest, ConfigureRegisteredServiceWithSameProfile) {
1664 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001665 new NiceMock<MockProfile>(
1666 control_interface(), metrics(), manager(), ""));
Paul Stewart2c575d22012-12-07 12:28:57 -08001667
1668 const string kProfileName0 = "profile0";
1669
1670 EXPECT_CALL(*profile0, GetRpcIdentifier())
1671 .WillRepeatedly(Return(kProfileName0));
1672
1673 AdoptProfile(manager(), profile0); // profile0 is now the ActiveProfile.
1674
Paul Stewartd2e1c362013-03-03 19:06:07 -08001675 const vector<uint8_t> ssid;
Paul Stewart2c575d22012-12-07 12:28:57 -08001676 scoped_refptr<MockWiFiService> service(
1677 new NiceMock<MockWiFiService>(control_interface(),
1678 dispatcher(),
1679 metrics(),
1680 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001681 wifi_provider_,
Paul Stewart2c575d22012-12-07 12:28:57 -08001682 ssid,
1683 "",
1684 "",
1685 false));
1686
1687 manager()->RegisterService(service);
1688 service->set_profile(profile0);
1689
Paul Stewart3c504012013-01-17 17:49:58 -08001690 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart2c575d22012-12-07 12:28:57 -08001691 .WillOnce(Return(service));
1692 EXPECT_CALL(*profile0, LoadService(ServiceRefPtr(service.get())))
1693 .Times(0);
1694 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1695 .WillOnce(Return(true));
1696 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1697 .Times(0);
1698
1699 KeyValueStore args;
1700 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1701 args.SetString(flimflam::kProfileProperty, kProfileName0);
1702 Error error;
1703 manager()->ConfigureService(args, &error);
1704 EXPECT_TRUE(error.IsSuccess());
1705 service->set_profile(NULL); // Breaks refcounting loop.
1706}
1707
Paul Stewart7f61e522012-03-22 11:13:45 -07001708// An unregistered service should remain unregistered, but its contents should
1709// be saved to the specified profile nonetheless.
1710TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1711 scoped_refptr<MockProfile> profile0(
Thieu Le5133b712013-02-19 14:47:21 -08001712 new NiceMock<MockProfile>(
1713 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001714 scoped_refptr<MockProfile> profile1(
Thieu Le5133b712013-02-19 14:47:21 -08001715 new NiceMock<MockProfile>(
1716 control_interface(), metrics(), manager(), ""));
Paul Stewart7f61e522012-03-22 11:13:45 -07001717
1718 const string kProfileName0 = "profile0";
1719 const string kProfileName1 = "profile1";
1720
1721 EXPECT_CALL(*profile0, GetRpcIdentifier())
1722 .WillRepeatedly(Return(kProfileName0));
1723 EXPECT_CALL(*profile1, GetRpcIdentifier())
1724 .WillRepeatedly(Return(kProfileName1));
1725
1726 AdoptProfile(manager(), profile0);
1727 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1728
Paul Stewartd2e1c362013-03-03 19:06:07 -08001729 const vector<uint8_t> ssid;
Paul Stewart7f61e522012-03-22 11:13:45 -07001730 scoped_refptr<MockWiFiService> service(
1731 new NiceMock<MockWiFiService>(control_interface(),
1732 dispatcher(),
1733 metrics(),
1734 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -08001735 wifi_provider_,
Paul Stewart7f61e522012-03-22 11:13:45 -07001736 ssid,
1737 "",
1738 "",
1739 false));
1740
1741 service->set_profile(profile1);
1742
Paul Stewart3c504012013-01-17 17:49:58 -08001743 EXPECT_CALL(*wifi_provider_, GetService(_, _))
Paul Stewart7f61e522012-03-22 11:13:45 -07001744 .WillOnce(Return(service));
1745 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1746 .WillOnce(Return(true));
1747 EXPECT_CALL(*profile0, AdoptService(_))
1748 .Times(0);
1749 EXPECT_CALL(*profile1, AdoptService(_))
1750 .Times(0);
1751
1752 KeyValueStore args;
1753 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1754 args.SetString(flimflam::kProfileProperty, kProfileName0);
1755 Error error;
1756 manager()->ConfigureService(args, &error);
1757 EXPECT_TRUE(error.IsSuccess());
1758}
1759
Paul Stewartd2e1c362013-03-03 19:06:07 -08001760TEST_F(ManagerTest, ConfigureServiceForProfileWithNoType) {
1761 KeyValueStore args;
1762 Error error;
1763 ServiceRefPtr service =
1764 manager()->ConfigureServiceForProfile("", args, &error);
1765 EXPECT_EQ(Error::kNotSupported, error.type());
1766 EXPECT_EQ("This method only supports WiFi services", error.message());
1767 EXPECT_EQ(NULL, service.get());
1768}
1769
1770TEST_F(ManagerTest, ConfigureServiceForProfileWithWrongType) {
1771 KeyValueStore args;
1772 args.SetString(flimflam::kTypeProperty, flimflam::kTypeCellular);
1773 Error error;
1774 ServiceRefPtr service =
1775 manager()->ConfigureServiceForProfile("", args, &error);
1776 EXPECT_EQ(Error::kNotSupported, error.type());
1777 EXPECT_EQ("This method only supports WiFi services", error.message());
1778 EXPECT_EQ(NULL, service.get());
1779}
1780
1781TEST_F(ManagerTest, ConfigureServiceForProfileWithMissingProfile) {
1782 KeyValueStore args;
1783 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1784 Error error;
1785 ServiceRefPtr service =
1786 manager()->ConfigureServiceForProfile("/profile/foo", args, &error);
1787 EXPECT_EQ(Error::kNotFound, error.type());
1788 EXPECT_EQ("Profile specified was not found", error.message());
1789 EXPECT_EQ(NULL, service.get());
1790}
1791
1792TEST_F(ManagerTest, ConfigureServiceForProfileWithProfileMismatch) {
1793 const string kProfileName0 = "profile0";
1794 const string kProfileName1 = "profile1";
1795 scoped_refptr<MockProfile> profile0(
1796 AddNamedMockProfileToManager(manager(), kProfileName0));
1797
1798 KeyValueStore args;
1799 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1800 args.SetString(flimflam::kProfileProperty, kProfileName1);
1801 Error error;
1802 ServiceRefPtr service =
1803 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1804 EXPECT_EQ(Error::kInvalidArguments, error.type());
1805 EXPECT_EQ("Profile argument does not match that in "
1806 "the configuration arguments", error.message());
1807 EXPECT_EQ(NULL, service.get());
1808}
1809
1810TEST_F(ManagerTest,
1811 ConfigureServiceForProfileWithNoMatchingServiceFailGetService) {
1812 const string kProfileName0 = "profile0";
1813 scoped_refptr<MockProfile> profile0(
1814 AddNamedMockProfileToManager(manager(), kProfileName0));
1815 KeyValueStore args;
1816 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1817 args.SetString(flimflam::kProfileProperty, kProfileName0);
1818
1819 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1820 .WillOnce(Return(WiFiServiceRefPtr()));
1821 EXPECT_CALL(*wifi_provider_, GetService(_, _))
1822 .WillOnce(Return(WiFiServiceRefPtr()));
1823 Error error;
1824 ServiceRefPtr service =
1825 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1826 // Since we didn't set the error in the GetService expectation above...
1827 EXPECT_TRUE(error.IsSuccess());
1828 EXPECT_EQ(NULL, service.get());
1829}
1830
1831TEST_F(ManagerTest, ConfigureServiceForProfileCreateNewService) {
1832 const string kProfileName0 = "profile0";
1833 scoped_refptr<MockProfile> profile0(
1834 AddNamedMockProfileToManager(manager(), kProfileName0));
1835
1836 KeyValueStore args;
1837 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1838
1839 scoped_refptr<MockWiFiService> mock_service(
1840 new NiceMock<MockWiFiService>(control_interface(),
1841 dispatcher(),
1842 metrics(),
1843 manager(),
1844 wifi_provider_,
1845 vector<uint8_t>(),
1846 flimflam::kModeManaged,
1847 flimflam::kSecurityNone,
1848 false));
1849 ServiceRefPtr mock_service_generic(mock_service.get());
1850 mock_service->set_profile(profile0);
1851 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1852 .WillOnce(Return(WiFiServiceRefPtr()));
1853 EXPECT_CALL(*wifi_provider_, GetService(_, _)).WillOnce(Return(mock_service));
1854 EXPECT_CALL(*profile0, UpdateService(mock_service_generic))
1855 .WillOnce(Return(true));
1856 Error error;
1857 ServiceRefPtr service =
1858 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
1859 EXPECT_TRUE(error.IsSuccess());
1860 EXPECT_EQ(mock_service.get(), service.get());
1861 mock_service->set_profile(NULL); // Breaks reference cycle.
1862}
1863
1864TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceByGUID) {
1865 scoped_refptr<MockService> mock_service(
1866 new NiceMock<MockService>(control_interface(),
1867 dispatcher(),
1868 metrics(),
1869 manager()));
1870 const string kGUID = "a guid";
1871 mock_service->set_guid(kGUID);
1872 manager()->RegisterService(mock_service);
1873 ServiceRefPtr mock_service_generic(mock_service.get());
1874
1875 const string kProfileName = "profile";
1876 scoped_refptr<MockProfile> profile(
1877 AddNamedMockProfileToManager(manager(), kProfileName));
1878 mock_service->set_profile(profile);
1879
1880 EXPECT_CALL(*mock_service, technology())
1881 .WillOnce(Return(Technology::kCellular))
1882 .WillOnce(Return(Technology::kWifi));
1883
1884 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _)).Times(0);
1885 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1886 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1887
1888 KeyValueStore args;
1889 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1890 args.SetString(flimflam::kGuidProperty, kGUID);
1891
1892 // The first attempt should fail because the service reports a technology
1893 // other than "WiFi".
1894 {
1895 Error error;
1896 ServiceRefPtr service =
1897 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1898 EXPECT_EQ(NULL, service.get());
1899 EXPECT_EQ(Error::kNotSupported, error.type());
1900 EXPECT_EQ("This GUID matches a non-WiFi service", error.message());
1901 }
1902
1903 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1904 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1905
1906 {
1907 Error error;
1908 ServiceRefPtr service =
1909 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1910 EXPECT_TRUE(error.IsSuccess());
1911 EXPECT_EQ(mock_service.get(), service.get());
1912 EXPECT_EQ(profile.get(), service->profile().get());
1913 }
1914 mock_service->set_profile(NULL); // Breaks reference cycle.
1915}
1916
1917TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceAndProfile) {
1918 const string kProfileName = "profile";
1919 scoped_refptr<MockProfile> profile(
1920 AddNamedMockProfileToManager(manager(), kProfileName));
1921
1922 scoped_refptr<MockWiFiService> mock_service(
1923 new NiceMock<MockWiFiService>(control_interface(),
1924 dispatcher(),
1925 metrics(),
1926 manager(),
1927 wifi_provider_,
1928 vector<uint8_t>(),
1929 flimflam::kModeManaged,
1930 flimflam::kSecurityNone,
1931 false));
1932 mock_service->set_profile(profile);
1933 ServiceRefPtr mock_service_generic(mock_service.get());
1934
1935 KeyValueStore args;
1936 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1937 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1938 .WillOnce(Return(mock_service));
1939 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1940 EXPECT_CALL(*profile, AdoptService(mock_service_generic)).Times(0);
1941 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1942 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1943
1944 Error error;
1945 ServiceRefPtr service =
1946 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1947 EXPECT_TRUE(error.IsSuccess());
1948 EXPECT_EQ(mock_service.get(), service.get());
1949 EXPECT_EQ(profile.get(), service->profile().get());
1950 mock_service->set_profile(NULL); // Breaks reference cycle.
1951}
1952
1953TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServiceEphemeralProfile) {
1954 const string kProfileName = "profile";
1955 scoped_refptr<MockProfile> profile(
1956 AddNamedMockProfileToManager(manager(), kProfileName));
1957
1958 scoped_refptr<MockWiFiService> mock_service(
1959 new NiceMock<MockWiFiService>(control_interface(),
1960 dispatcher(),
1961 metrics(),
1962 manager(),
1963 wifi_provider_,
1964 vector<uint8_t>(),
1965 flimflam::kModeManaged,
1966 flimflam::kSecurityNone,
1967 false));
1968 mock_service->set_profile(GetEphemeralProfile(manager()));
1969 ServiceRefPtr mock_service_generic(mock_service.get());
1970
1971 KeyValueStore args;
1972 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1973 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
1974 .WillOnce(Return(mock_service));
1975 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
1976 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
1977 EXPECT_CALL(*profile, UpdateService(mock_service_generic)).Times(1);
1978
1979 Error error;
1980 ServiceRefPtr service =
1981 manager()->ConfigureServiceForProfile(kProfileName, args, &error);
1982 EXPECT_TRUE(error.IsSuccess());
1983 EXPECT_EQ(mock_service.get(), service.get());
1984 EXPECT_EQ(profile.get(), service->profile().get());
1985 mock_service->set_profile(NULL); // Breaks reference cycle.
1986}
1987
1988TEST_F(ManagerTest, ConfigureServiceForProfileMatchingServicePrecedingProfile) {
1989 const string kProfileName0 = "profile0";
1990 scoped_refptr<MockProfile> profile0(
1991 AddNamedMockProfileToManager(manager(), kProfileName0));
1992 const string kProfileName1 = "profile1";
1993 scoped_refptr<MockProfile> profile1(
1994 AddNamedMockProfileToManager(manager(), kProfileName1));
1995
1996 scoped_refptr<MockWiFiService> mock_service(
1997 new NiceMock<MockWiFiService>(control_interface(),
1998 dispatcher(),
1999 metrics(),
2000 manager(),
2001 wifi_provider_,
2002 vector<uint8_t>(),
2003 flimflam::kModeManaged,
2004 flimflam::kSecurityNone,
2005 false));
2006 manager()->RegisterService(mock_service);
2007 mock_service->set_profile(profile0);
2008 ServiceRefPtr mock_service_generic(mock_service.get());
2009
2010 KeyValueStore args;
2011 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2012 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2013 .WillOnce(Return(mock_service));
2014 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2015 EXPECT_CALL(*profile0, AbandonService(_)).Times(0);
2016 EXPECT_CALL(*profile1, AdoptService(_)).Times(0);
2017 // This happens once to make the service loadable for the ConfigureService
2018 // below, and a second time after the service is modified.
2019 EXPECT_CALL(*profile1, ConfigureService(mock_service_generic)).Times(0);
2020 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _)).Times(0);
2021 EXPECT_CALL(*mock_service, Configure(_, _)).Times(1);
2022 EXPECT_CALL(*profile1, UpdateService(mock_service_generic)).Times(1);
2023
2024 Error error;
2025 ServiceRefPtr service =
2026 manager()->ConfigureServiceForProfile(kProfileName1, args, &error);
2027 EXPECT_TRUE(error.IsSuccess());
2028 EXPECT_EQ(mock_service.get(), service.get());
2029 mock_service->set_profile(NULL); // Breaks reference cycle.
2030}
2031
2032TEST_F(ManagerTest,
2033 ConfigureServiceForProfileMatchingServiceProceedingProfile) {
2034 const string kProfileName0 = "profile0";
2035 scoped_refptr<MockProfile> profile0(
2036 AddNamedMockProfileToManager(manager(), kProfileName0));
2037 const string kProfileName1 = "profile1";
2038 scoped_refptr<MockProfile> profile1(
2039 AddNamedMockProfileToManager(manager(), kProfileName1));
2040
2041 scoped_refptr<MockWiFiService> matching_service(
2042 new StrictMock<MockWiFiService>(control_interface(),
2043 dispatcher(),
2044 metrics(),
2045 manager(),
2046 wifi_provider_,
2047 vector<uint8_t>(),
2048 flimflam::kModeManaged,
2049 flimflam::kSecurityNone,
2050 false));
2051 matching_service->set_profile(profile1);
2052
2053 // We need to get rid of our reference to this mock service as soon
2054 // as Manager::ConfigureServiceForProfile() takes a reference in its
2055 // call to WiFiProvider::CreateTemporaryService(). This way the
2056 // latter function can keep a DCHECK(service->HasOneRef() even in
2057 // unit tests.
2058 temp_mock_service_ =
2059 new NiceMock<MockWiFiService>(control_interface(),
2060 dispatcher(),
2061 metrics(),
2062 manager(),
2063 wifi_provider_,
2064 vector<uint8_t>(),
2065 flimflam::kModeManaged,
2066 flimflam::kSecurityNone,
2067 false);
2068
2069 // Only hold a pointer here so we don't affect the refcount.
2070 MockWiFiService *mock_service_ptr = temp_mock_service_.get();
2071
2072 KeyValueStore args;
2073 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
2074 EXPECT_CALL(*wifi_provider_, FindSimilarService(_, _))
2075 .WillOnce(Return(matching_service));
2076 EXPECT_CALL(*wifi_provider_, GetService(_, _)).Times(0);
2077 EXPECT_CALL(*profile1, AbandonService(_)).Times(0);
2078 EXPECT_CALL(*profile0, AdoptService(_)).Times(0);
2079 EXPECT_CALL(*wifi_provider_, CreateTemporaryService(_, _))
2080 .WillOnce(InvokeWithoutArgs(this, &ManagerTest::ReleaseTempMockService));
2081 EXPECT_CALL(*profile0, ConfigureService(IsRefPtrTo(mock_service_ptr)))
2082 .Times(1);
2083 EXPECT_CALL(*mock_service_ptr, Configure(_, _)).Times(1);
2084 EXPECT_CALL(*profile0, UpdateService(IsRefPtrTo(mock_service_ptr))).Times(1);
2085
2086 Error error;
2087 ServiceRefPtr service =
2088 manager()->ConfigureServiceForProfile(kProfileName0, args, &error);
2089 EXPECT_TRUE(error.IsSuccess());
2090 EXPECT_EQ(NULL, service.get());
2091 EXPECT_EQ(profile1.get(), matching_service->profile().get());
2092}
2093
Paul Stewart7a20aa42013-01-17 12:21:41 -08002094TEST_F(ManagerTest, FindMatchingService) {
2095 KeyValueStore args;
2096 {
2097 Error error;
2098 ServiceRefPtr service = manager()->FindMatchingService(args, &error);
2099 EXPECT_EQ(Error::kNotFound, error.type());
2100 }
2101
2102 scoped_refptr<MockService> mock_service0(
2103 new NiceMock<MockService>(control_interface(),
2104 dispatcher(),
2105 metrics(),
2106 manager()));
2107 scoped_refptr<MockService> mock_service1(
2108 new NiceMock<MockService>(control_interface(),
2109 dispatcher(),
2110 metrics(),
2111 manager()));
2112 manager()->RegisterService(mock_service0);
2113 manager()->RegisterService(mock_service1);
2114 EXPECT_CALL(*mock_service0, DoPropertiesMatch(_))
2115 .WillOnce(Return(true))
2116 .WillRepeatedly(Return(false));
2117 {
2118 Error error;
2119 EXPECT_EQ(mock_service0, manager()->FindMatchingService(args, &error));
2120 EXPECT_TRUE(error.IsSuccess());
2121 }
2122 EXPECT_CALL(*mock_service1, DoPropertiesMatch(_))
2123 .WillOnce(Return(true))
2124 .WillRepeatedly(Return(false));
2125 {
2126 Error error;
2127 EXPECT_EQ(mock_service1, manager()->FindMatchingService(args, &error));
2128 EXPECT_TRUE(error.IsSuccess());
2129 }
2130 {
2131 Error error;
2132 EXPECT_FALSE(manager()->FindMatchingService(args, &error));
2133 EXPECT_EQ(Error::kNotFound, error.type());
2134 }
2135}
2136
Paul Stewart22aa71b2011-09-16 12:15:11 -07002137TEST_F(ManagerTest, TechnologyOrder) {
2138 Error error;
2139 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
2140 string(flimflam::kTypeWifi), &error);
2141 ASSERT_TRUE(error.IsSuccess());
2142 EXPECT_EQ(manager()->GetTechnologyOrder(),
2143 string(flimflam::kTypeEthernet) + "," +
2144 string(flimflam::kTypeWifi));
2145
2146 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
2147 string(flimflam::kTypeWifi), &error);
2148 ASSERT_FALSE(error.IsSuccess());
2149 EXPECT_EQ(Error::kInvalidArguments, error.type());
2150 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
2151 string(flimflam::kTypeWifi),
2152 manager()->GetTechnologyOrder());
2153}
2154
2155TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00002156 // TODO(quiche): Some of these tests would probably fit better in
2157 // service_unittest, since the actual comparison of Services is
2158 // implemented in Service. (crosbug.com/23370)
2159
Paul Stewart22aa71b2011-09-16 12:15:11 -07002160 scoped_refptr<MockService> mock_service0(
2161 new NiceMock<MockService>(control_interface(),
2162 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002163 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002164 manager()));
2165 scoped_refptr<MockService> mock_service1(
2166 new NiceMock<MockService>(control_interface(),
2167 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002168 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07002169 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002170
2171 manager()->RegisterService(mock_service0);
2172 manager()->RegisterService(mock_service1);
2173
Darin Petkov457728b2013-01-09 09:49:08 +01002174 // Services should already be sorted by |unique_name_|
Paul Stewart22aa71b2011-09-16 12:15:11 -07002175 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2176
2177 // Asking explictly to sort services should not change anything
Paul Stewartdfa46052012-06-26 09:44:14 -07002178 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002179 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2180
2181 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01002182 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002183 manager()->UpdateService(mock_service1);
2184 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2185
2186 // Security
mukesh agrawal43970a22013-02-15 16:00:07 -08002187 mock_service0->SetSecurity(Service::kCryptoAes, true, true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002188 manager()->UpdateService(mock_service0);
2189 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2190
2191 // Technology
Joshua Kroll053fa822012-06-05 09:50:43 -07002192 EXPECT_CALL(*mock_service0.get(), technology())
2193 .WillRepeatedly(Return((Technology::kWifi)));
2194 EXPECT_CALL(*mock_service1.get(), technology())
2195 .WillRepeatedly(Return(Technology::kEthernet));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002196
2197 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08002198 // Default technology ordering should favor Ethernet over WiFi.
Paul Stewartdfa46052012-06-26 09:44:14 -07002199 manager()->SortServicesTask();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002200 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2201
2202 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
2203 string(flimflam::kTypeEthernet), &error);
2204 EXPECT_TRUE(error.IsSuccess());
2205 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2206
Gaurav Shah435de2c2011-11-17 19:01:07 -08002207 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002208 mock_service0->set_priority(1);
2209 manager()->UpdateService(mock_service0);
2210 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2211
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002212 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00002213 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07002214 manager()->UpdateService(mock_service1);
2215 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2216
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002217 // Auto-connect.
2218 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002219 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002220 mock_service1->set_auto_connect(false);
2221 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07002222 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2223
Paul Stewartdf3c0a82012-11-09 15:54:33 -08002224 // Test is-dependent-on. It doesn't make sense to have this ranking compare
2225 // to any of the others below, so we reset to the default state after
2226 // testing.
2227 EXPECT_CALL(*mock_service1.get(),
2228 IsDependentOn(ServiceRefPtr(mock_service0.get())))
2229 .WillOnce(Return(true))
2230 .WillRepeatedly(Return(false));
2231 manager()->UpdateService(mock_service1);
2232 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2233 manager()->UpdateService(mock_service0);
2234 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2235
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002236 // Connectable.
2237 mock_service1->set_connectable(true);
2238 manager()->UpdateService(mock_service1);
2239 mock_service0->set_connectable(false);
2240 manager()->UpdateService(mock_service0);
2241 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2242
2243 // IsFailed.
2244 EXPECT_CALL(*mock_service0.get(), state())
2245 .WillRepeatedly(Return(Service::kStateIdle));
2246 EXPECT_CALL(*mock_service0.get(), IsFailed())
2247 .WillRepeatedly(Return(false));
2248 manager()->UpdateService(mock_service0);
2249 EXPECT_CALL(*mock_service0.get(), state())
2250 .WillRepeatedly(Return(Service::kStateFailure));
2251 EXPECT_CALL(*mock_service1.get(), IsFailed())
2252 .WillRepeatedly(Return(true));
2253 manager()->UpdateService(mock_service1);
2254 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2255
2256 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07002257 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002258 .WillRepeatedly(Return(Service::kStateAssociating));
2259 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08002260 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07002261 manager()->UpdateService(mock_service1);
2262 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2263
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002264 // Connected.
2265 EXPECT_CALL(*mock_service0.get(), state())
Paul Stewarta121c442012-06-09 14:12:58 -07002266 .WillRepeatedly(Return(Service::kStatePortal));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002267 EXPECT_CALL(*mock_service0.get(), IsConnected())
2268 .WillRepeatedly(Return(true));
2269 manager()->UpdateService(mock_service0);
2270 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
2271
Paul Stewarta121c442012-06-09 14:12:58 -07002272 // Portal.
2273 EXPECT_CALL(*mock_service1.get(), state())
2274 .WillRepeatedly(Return(Service::kStateConnected));
2275 EXPECT_CALL(*mock_service1.get(), IsConnected())
2276 .WillRepeatedly(Return(true));
2277 manager()->UpdateService(mock_service1);
2278 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
2279
Paul Stewart22aa71b2011-09-16 12:15:11 -07002280 manager()->DeregisterService(mock_service0);
2281 manager()->DeregisterService(mock_service1);
2282}
2283
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002284TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002285 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002286 SetMetrics(&mock_metrics);
Thieu Lea20cbc22012-01-09 22:01:43 +00002287
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002288 scoped_refptr<MockService> mock_service0(
2289 new NiceMock<MockService>(control_interface(),
2290 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002291 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002292 manager()));
2293 scoped_refptr<MockService> mock_service1(
2294 new NiceMock<MockService>(control_interface(),
2295 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002296 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002297 manager()));
2298
2299 scoped_refptr<MockConnection> mock_connection0(
2300 new NiceMock<MockConnection>(device_info_.get()));
2301 scoped_refptr<MockConnection> mock_connection1(
2302 new NiceMock<MockConnection>(device_info_.get()));
2303
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002304 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002305 manager()->RegisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002306 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002307 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002308 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002309 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002310
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002311 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002312 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002313
2314 mock_service1->set_priority(1);
2315 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002316 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002317
2318 mock_service1->set_priority(0);
2319 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002320 manager()->SortServicesTask();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002321
Paul Stewartce4ec192012-03-14 12:53:46 -07002322 mock_service0->set_mock_connection(mock_connection0);
2323 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002324
2325 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00002326 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002327 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002328
Darin Petkova5e07ef2012-07-09 14:27:57 +02002329 ServiceWatcher service_watcher;
2330 int tag =
2331 manager()->RegisterDefaultServiceCallback(
2332 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2333 service_watcher.AsWeakPtr()));
2334 EXPECT_EQ(1, tag);
2335
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002336 mock_service1->set_priority(1);
2337 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
2338 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002339 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_));
Thieu Lea20cbc22012-01-09 22:01:43 +00002340 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartdfa46052012-06-26 09:44:14 -07002341 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002342
Darin Petkova5e07ef2012-07-09 14:27:57 +02002343 manager()->DeregisterDefaultServiceCallback(tag);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002344 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Darin Petkova5e07ef2012-07-09 14:27:57 +02002345 EXPECT_CALL(service_watcher, OnDefaultServiceChanged(_)).Times(0);
Thieu Lea20cbc22012-01-09 22:01:43 +00002346 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002347 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002348 manager()->DeregisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07002349 CompleteServiceSort();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002350
Paul Stewartce4ec192012-03-14 12:53:46 -07002351 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002352 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002353 manager()->DeregisterService(mock_service0);
Paul Stewartdfa46052012-06-26 09:44:14 -07002354 CompleteServiceSort();
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002355
2356 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartdfa46052012-06-26 09:44:14 -07002357 manager()->SortServicesTask();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08002358}
2359
Darin Petkova5e07ef2012-07-09 14:27:57 +02002360TEST_F(ManagerTest, NotifyDefaultServiceChanged) {
2361 EXPECT_EQ(0, manager()->default_service_callback_tag_);
2362 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2363
Thieu Le6c1e3bb2013-02-06 15:20:35 -08002364 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01002365 SetMetrics(&mock_metrics);
Darin Petkova5e07ef2012-07-09 14:27:57 +02002366
2367 scoped_refptr<MockService> mock_service(
2368 new NiceMock<MockService>(
2369 control_interface(), dispatcher(), metrics(), manager()));
2370 ServiceRefPtr service = mock_service;
2371 ServiceRefPtr null_service;
2372
2373 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2374 manager()->NotifyDefaultServiceChanged(null_service);
2375
2376 ServiceWatcher service_watcher1;
2377 ServiceWatcher service_watcher2;
2378 int tag1 =
2379 manager()->RegisterDefaultServiceCallback(
2380 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2381 service_watcher1.AsWeakPtr()));
2382 EXPECT_EQ(1, tag1);
2383 int tag2 =
2384 manager()->RegisterDefaultServiceCallback(
2385 Bind(&ServiceWatcher::OnDefaultServiceChanged,
2386 service_watcher2.AsWeakPtr()));
2387 EXPECT_EQ(2, tag2);
2388
2389 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(null_service));
2390 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(null_service));
2391 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
2392 manager()->NotifyDefaultServiceChanged(null_service);
2393
2394 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(service));
2395 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2396 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2397 manager()->NotifyDefaultServiceChanged(mock_service);
2398
2399 manager()->DeregisterDefaultServiceCallback(tag1);
2400 EXPECT_CALL(service_watcher1, OnDefaultServiceChanged(_)).Times(0);
2401 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(service));
2402 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2403 manager()->NotifyDefaultServiceChanged(mock_service);
2404 EXPECT_EQ(1, manager()->default_service_callbacks_.size());
2405
2406 manager()->DeregisterDefaultServiceCallback(tag2);
2407 EXPECT_CALL(service_watcher2, OnDefaultServiceChanged(_)).Times(0);
2408 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(service.get()));
2409 manager()->NotifyDefaultServiceChanged(mock_service);
2410
2411 EXPECT_EQ(2, manager()->default_service_callback_tag_);
2412 EXPECT_TRUE(manager()->default_service_callbacks_.empty());
2413}
2414
Gaurav Shah435de2c2011-11-17 19:01:07 -08002415TEST_F(ManagerTest, AvailableTechnologies) {
2416 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
2417 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002418 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002419 manager(),
2420 "null4",
2421 "addr4",
2422 0));
2423 manager()->RegisterDevice(mock_devices_[0]);
2424 manager()->RegisterDevice(mock_devices_[1]);
2425 manager()->RegisterDevice(mock_devices_[2]);
2426 manager()->RegisterDevice(mock_devices_[3]);
2427
2428 ON_CALL(*mock_devices_[0].get(), technology())
2429 .WillByDefault(Return(Technology::kEthernet));
2430 ON_CALL(*mock_devices_[1].get(), technology())
2431 .WillByDefault(Return(Technology::kWifi));
2432 ON_CALL(*mock_devices_[2].get(), technology())
2433 .WillByDefault(Return(Technology::kCellular));
2434 ON_CALL(*mock_devices_[3].get(), technology())
2435 .WillByDefault(Return(Technology::kWifi));
2436
2437 set<string> expected_technologies;
2438 expected_technologies.insert(Technology::NameFromIdentifier(
2439 Technology::kEthernet));
2440 expected_technologies.insert(Technology::NameFromIdentifier(
2441 Technology::kWifi));
2442 expected_technologies.insert(Technology::NameFromIdentifier(
2443 Technology::kCellular));
2444 Error error;
2445 vector<string> technologies = manager()->AvailableTechnologies(&error);
2446
2447 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2448 ContainerEq(expected_technologies));
2449}
2450
2451TEST_F(ManagerTest, ConnectedTechnologies) {
2452 scoped_refptr<MockService> connected_service1(
2453 new NiceMock<MockService>(control_interface(),
2454 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002455 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002456 manager()));
2457 scoped_refptr<MockService> connected_service2(
2458 new NiceMock<MockService>(control_interface(),
2459 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002460 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002461 manager()));
2462 scoped_refptr<MockService> disconnected_service1(
2463 new NiceMock<MockService>(control_interface(),
2464 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002465 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002466 manager()));
2467 scoped_refptr<MockService> disconnected_service2(
2468 new NiceMock<MockService>(control_interface(),
2469 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002470 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002471 manager()));
2472
2473 ON_CALL(*connected_service1.get(), IsConnected())
2474 .WillByDefault(Return(true));
2475 ON_CALL(*connected_service2.get(), IsConnected())
2476 .WillByDefault(Return(true));
2477
2478 manager()->RegisterService(connected_service1);
2479 manager()->RegisterService(connected_service2);
2480 manager()->RegisterService(disconnected_service1);
2481 manager()->RegisterService(disconnected_service2);
2482
2483 manager()->RegisterDevice(mock_devices_[0]);
2484 manager()->RegisterDevice(mock_devices_[1]);
2485 manager()->RegisterDevice(mock_devices_[2]);
2486 manager()->RegisterDevice(mock_devices_[3]);
2487
2488 ON_CALL(*mock_devices_[0].get(), technology())
2489 .WillByDefault(Return(Technology::kEthernet));
2490 ON_CALL(*mock_devices_[1].get(), technology())
2491 .WillByDefault(Return(Technology::kWifi));
2492 ON_CALL(*mock_devices_[2].get(), technology())
2493 .WillByDefault(Return(Technology::kCellular));
2494 ON_CALL(*mock_devices_[3].get(), technology())
2495 .WillByDefault(Return(Technology::kWifi));
2496
2497 mock_devices_[0]->SelectService(connected_service1);
2498 mock_devices_[1]->SelectService(disconnected_service1);
2499 mock_devices_[2]->SelectService(disconnected_service2);
2500 mock_devices_[3]->SelectService(connected_service2);
2501
2502 set<string> expected_technologies;
2503 expected_technologies.insert(Technology::NameFromIdentifier(
2504 Technology::kEthernet));
2505 expected_technologies.insert(Technology::NameFromIdentifier(
2506 Technology::kWifi));
2507 Error error;
2508
2509 vector<string> technologies = manager()->ConnectedTechnologies(&error);
2510 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
2511 ContainerEq(expected_technologies));
2512}
2513
2514TEST_F(ManagerTest, DefaultTechnology) {
2515 scoped_refptr<MockService> connected_service(
2516 new NiceMock<MockService>(control_interface(),
2517 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002518 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002519 manager()));
2520 scoped_refptr<MockService> disconnected_service(
2521 new NiceMock<MockService>(control_interface(),
2522 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002523 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08002524 manager()));
2525
2526 // Connected. WiFi.
2527 ON_CALL(*connected_service.get(), IsConnected())
2528 .WillByDefault(Return(true));
2529 ON_CALL(*connected_service.get(), state())
2530 .WillByDefault(Return(Service::kStateConnected));
2531 ON_CALL(*connected_service.get(), technology())
2532 .WillByDefault(Return(Technology::kWifi));
2533
2534 // Disconnected. Ethernet.
2535 ON_CALL(*disconnected_service.get(), technology())
2536 .WillByDefault(Return(Technology::kEthernet));
2537
2538 manager()->RegisterService(disconnected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002539 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002540 Error error;
2541 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
2542
2543
2544 manager()->RegisterService(connected_service);
Paul Stewartdfa46052012-06-26 09:44:14 -07002545 CompleteServiceSort();
Gaurav Shah435de2c2011-11-17 19:01:07 -08002546 // Connected service should be brought to the front now.
2547 string expected_technology =
2548 Technology::NameFromIdentifier(Technology::kWifi);
2549 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
2550}
2551
Paul Stewart212d60f2012-07-12 10:59:13 -07002552TEST_F(ManagerTest, Stop) {
2553 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002554 new NiceMock<MockProfile>(
2555 control_interface(), metrics(), manager(), ""));
Paul Stewart212d60f2012-07-12 10:59:13 -07002556 AdoptProfile(manager(), profile);
2557 scoped_refptr<MockService> service(
Thieu Le1271d682011-11-02 22:48:19 +00002558 new NiceMock<MockService>(control_interface(),
2559 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002560 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00002561 manager()));
Paul Stewart212d60f2012-07-12 10:59:13 -07002562 manager()->RegisterService(service);
2563 manager()->RegisterDevice(mock_devices_[0]);
2564 EXPECT_CALL(*profile.get(),
2565 UpdateDevice(DeviceRefPtr(mock_devices_[0].get())))
2566 .WillOnce(Return(true));
2567 EXPECT_CALL(*profile.get(), Save()).WillOnce(Return(true));
2568 EXPECT_CALL(*service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00002569 manager()->Stop();
2570}
2571
mukesh agrawal00917ce2011-11-22 23:56:55 +00002572TEST_F(ManagerTest, UpdateServiceConnected) {
2573 scoped_refptr<MockService> mock_service(
2574 new NiceMock<MockService>(control_interface(),
2575 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002576 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00002577 manager()));
2578 manager()->RegisterService(mock_service);
2579 EXPECT_FALSE(mock_service->favorite());
2580 EXPECT_FALSE(mock_service->auto_connect());
2581
Gaurav Shah435de2c2011-11-17 19:01:07 -08002582 EXPECT_CALL(*mock_service.get(), IsConnected())
2583 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00002584 manager()->UpdateService(mock_service);
2585 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2586 // to mock out MakeFavorite. And mocking that out would break the
2587 // SortServices test. (crosbug.com/23370)
2588 EXPECT_TRUE(mock_service->favorite());
2589 EXPECT_TRUE(mock_service->auto_connect());
2590}
2591
Thieu Led4e9e552012-02-16 16:26:07 -08002592TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
2593 // This tests the case where the user connects to a service that is
2594 // currently associated with a profile. We want to make sure that the
2595 // favorite flag is set and that the flag is saved to the current
2596 // profile.
2597 scoped_refptr<MockService> mock_service(
2598 new NiceMock<MockService>(control_interface(),
2599 dispatcher(),
2600 metrics(),
2601 manager()));
2602 manager()->RegisterService(mock_service);
2603 EXPECT_FALSE(mock_service->favorite());
2604 EXPECT_FALSE(mock_service->auto_connect());
2605
Gary Moraind93615e2012-04-27 11:50:03 -07002606 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002607 new MockProfile(
2608 control_interface(), metrics(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08002609
Gary Moraind93615e2012-04-27 11:50:03 -07002610 mock_service->set_profile(profile);
2611 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08002612 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07002613 EXPECT_CALL(*profile,
2614 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08002615 manager()->UpdateService(mock_service);
2616 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
2617 // to mock out MakeFavorite. And mocking that out would break the
2618 // SortServices test. (crosbug.com/23370)
2619 EXPECT_TRUE(mock_service->favorite());
2620 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07002621 // This releases the ref on the mock profile.
2622 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08002623}
2624
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002625TEST_F(ManagerTest, SaveSuccessfulService) {
2626 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002627 new StrictMock<MockProfile>(
2628 control_interface(), metrics(), manager(), ""));
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002629 AdoptProfile(manager(), profile);
2630 scoped_refptr<MockService> service(
2631 new NiceMock<MockService>(control_interface(),
2632 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08002633 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08002634 manager()));
2635
2636 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
2637 ServiceRefPtr expect_service(service.get());
2638
2639 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
2640 .WillOnce(Return(false));
2641 manager()->RegisterService(service);
2642
2643 EXPECT_CALL(*service.get(), state())
2644 .WillRepeatedly(Return(Service::kStateConnected));
2645 EXPECT_CALL(*service.get(), IsConnected())
2646 .WillRepeatedly(Return(true));
2647 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
2648 .WillOnce(Return(true));
2649 manager()->UpdateService(service);
2650}
2651
Darin Petkove7c6ad32012-06-29 10:22:09 +02002652TEST_F(ManagerTest, UpdateDevice) {
Thieu Le5133b712013-02-19 14:47:21 -08002653 MockProfile *profile0 =
2654 new MockProfile(control_interface(), metrics(), manager(), "");
2655 MockProfile *profile1 =
2656 new MockProfile(control_interface(), metrics(), manager(), "");
2657 MockProfile *profile2 =
2658 new MockProfile(control_interface(), metrics(), manager(), "");
Darin Petkove7c6ad32012-06-29 10:22:09 +02002659 AdoptProfile(manager(), profile0); // Passes ownership.
2660 AdoptProfile(manager(), profile1); // Passes ownership.
2661 AdoptProfile(manager(), profile2); // Passes ownership.
2662 DeviceRefPtr device_ref(mock_devices_[0].get());
2663 EXPECT_CALL(*profile0, UpdateDevice(device_ref)).Times(0);
2664 EXPECT_CALL(*profile1, UpdateDevice(device_ref)).WillOnce(Return(true));
2665 EXPECT_CALL(*profile2, UpdateDevice(device_ref)).WillOnce(Return(false));
2666 manager()->UpdateDevice(mock_devices_[0]);
2667}
2668
Paul Stewart1b253142012-01-26 14:05:52 -08002669TEST_F(ManagerTest, EnumerateProfiles) {
2670 vector<string> profile_paths;
2671 for (size_t i = 0; i < 10; i++) {
2672 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08002673 new StrictMock<MockProfile>(
2674 control_interface(), metrics(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05002675 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08002676 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
2677 .WillOnce(Return(profile_paths.back()));
2678 AdoptProfile(manager(), profile);
2679 }
2680
2681 Error error;
2682 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
2683 EXPECT_TRUE(error.IsSuccess());
2684 EXPECT_EQ(profile_paths.size(), returned_paths.size());
2685 for (size_t i = 0; i < profile_paths.size(); i++) {
2686 EXPECT_EQ(profile_paths[i], returned_paths[i]);
2687 }
2688}
2689
mukesh agrawal8a3188d2011-12-01 20:56:44 +00002690TEST_F(ManagerTest, AutoConnectOnRegister) {
2691 MockServiceRefPtr service = MakeAutoConnectableService();
2692 EXPECT_CALL(*service.get(), AutoConnect());
2693 manager()->RegisterService(service);
2694 dispatcher()->DispatchPendingEvents();
2695}
2696
2697TEST_F(ManagerTest, AutoConnectOnUpdate) {
2698 MockServiceRefPtr service1 = MakeAutoConnectableService();
2699 service1->set_priority(1);
2700 MockServiceRefPtr service2 = MakeAutoConnectableService();
2701 service2->set_priority(2);
2702 manager()->RegisterService(service1);
2703 manager()->RegisterService(service2);
2704 dispatcher()->DispatchPendingEvents();
2705
2706 EXPECT_CALL(*service1.get(), AutoConnect());
2707 EXPECT_CALL(*service2.get(), state())
2708 .WillRepeatedly(Return(Service::kStateFailure));
2709 EXPECT_CALL(*service2.get(), IsFailed())
2710 .WillRepeatedly(Return(true));
2711 EXPECT_CALL(*service2.get(), IsConnected())
2712 .WillRepeatedly(Return(false));
2713 manager()->UpdateService(service2);
2714 dispatcher()->DispatchPendingEvents();
2715}
2716
2717TEST_F(ManagerTest, AutoConnectOnDeregister) {
2718 MockServiceRefPtr service1 = MakeAutoConnectableService();
2719 service1->set_priority(1);
2720 MockServiceRefPtr service2 = MakeAutoConnectableService();
2721 service2->set_priority(2);
2722 manager()->RegisterService(service1);
2723 manager()->RegisterService(service2);
2724 dispatcher()->DispatchPendingEvents();
2725
2726 EXPECT_CALL(*service1.get(), AutoConnect());
2727 manager()->DeregisterService(service2);
2728 dispatcher()->DispatchPendingEvents();
2729}
2730
Darin Petkov3ec55342012-09-28 14:04:44 +02002731TEST_F(ManagerTest, AutoConnectOnPowerStateSuspending) {
2732 MockServiceRefPtr service = MakeAutoConnectableService();
2733 SetPowerState(PowerManagerProxyDelegate::kSuspending);
2734 SetPowerManager();
2735 EXPECT_CALL(*service, AutoConnect()).Times(0);
2736 manager()->RegisterService(service);
2737 dispatcher()->DispatchPendingEvents();
2738}
2739
Darin Petkovca621542012-07-25 14:25:56 +02002740TEST_F(ManagerTest, AutoConnectOnPowerStateMem) {
2741 MockServiceRefPtr service = MakeAutoConnectableService();
2742 SetPowerState(PowerManagerProxyDelegate::kMem);
2743 SetPowerManager();
2744 EXPECT_CALL(*service, AutoConnect()).Times(0);
2745 manager()->RegisterService(service);
2746 dispatcher()->DispatchPendingEvents();
2747}
2748
2749TEST_F(ManagerTest, AutoConnectOnPowerStateOn) {
2750 MockServiceRefPtr service = MakeAutoConnectableService();
2751 SetPowerState(PowerManagerProxyDelegate::kOn);
2752 SetPowerManager();
2753 EXPECT_CALL(*service, AutoConnect());
2754 manager()->RegisterService(service);
2755 dispatcher()->DispatchPendingEvents();
2756}
2757
2758TEST_F(ManagerTest, AutoConnectOnPowerStateUnknown) {
2759 MockServiceRefPtr service = MakeAutoConnectableService();
2760 SetPowerState(PowerManagerProxyDelegate::kUnknown);
2761 SetPowerManager();
2762 EXPECT_CALL(*service, AutoConnect());
2763 manager()->RegisterService(service);
2764 dispatcher()->DispatchPendingEvents();
2765}
2766
Paul Stewart63864b62012-11-07 15:10:55 -08002767TEST_F(ManagerTest, AutoConnectWhileNotRunning) {
2768 SetRunning(false);
2769 MockServiceRefPtr service = MakeAutoConnectableService();
2770 EXPECT_CALL(*service, AutoConnect()).Times(0);
2771 manager()->RegisterService(service);
2772 dispatcher()->DispatchPendingEvents();
2773}
2774
Darin Petkovca621542012-07-25 14:25:56 +02002775TEST_F(ManagerTest, OnPowerStateChanged) {
2776 MockServiceRefPtr service = MakeAutoConnectableService();
2777 SetPowerState(PowerManagerProxyDelegate::kOn);
2778 SetPowerManager();
2779 EXPECT_CALL(*service, AutoConnect());
2780 manager()->RegisterService(service);
mukesh agrawal784566d2012-08-08 18:32:58 -07002781 manager()->RegisterDevice(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002782 dispatcher()->DispatchPendingEvents();
2783
mukesh agrawal784566d2012-08-08 18:32:58 -07002784 EXPECT_CALL(*mock_devices_[0], OnAfterResume());
Darin Petkovca621542012-07-25 14:25:56 +02002785 OnPowerStateChanged(PowerManagerProxyDelegate::kOn);
2786 EXPECT_CALL(*service, AutoConnect());
2787 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002788 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002789
mukesh agrawal784566d2012-08-08 18:32:58 -07002790 EXPECT_CALL(*mock_devices_[0], OnBeforeSuspend());
Darin Petkovca621542012-07-25 14:25:56 +02002791 OnPowerStateChanged(PowerManagerProxyDelegate::kMem);
2792 EXPECT_CALL(*service, AutoConnect()).Times(0);
2793 dispatcher()->DispatchPendingEvents();
mukesh agrawal784566d2012-08-08 18:32:58 -07002794 Mock::VerifyAndClearExpectations(mock_devices_[0]);
Darin Petkovca621542012-07-25 14:25:56 +02002795}
2796
Darin Petkov3ec55342012-09-28 14:04:44 +02002797TEST_F(ManagerTest, AddTerminationAction) {
2798 EXPECT_CALL(*power_manager_, AddSuspendDelayCallback(_, _));
Daniel Eratf9753672013-01-24 10:17:02 -08002799 EXPECT_CALL(*power_manager_, RegisterSuspendDelay(_, _, _));
Darin Petkov3ec55342012-09-28 14:04:44 +02002800 SetPowerManager();
2801 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2802 manager()->AddTerminationAction("action1", base::Closure());
2803 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2804 manager()->AddTerminationAction("action2", base::Closure());
2805}
2806
2807TEST_F(ManagerTest, RemoveTerminationAction) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002808 const char kKey1[] = "action1";
2809 const char kKey2[] = "action2";
2810 const int kSuspendDelayId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002811
2812 MockPowerManager &power_manager = *power_manager_;
2813 SetPowerManager();
2814
2815 // Removing an action when the hook table is empty should not result in any
2816 // calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002817 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002818 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2819 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2820 manager()->RemoveTerminationAction("unknown");
2821 Mock::VerifyAndClearExpectations(&power_manager);
2822
Daniel Eratf9753672013-01-24 10:17:02 -08002823 EXPECT_CALL(power_manager, RegisterSuspendDelay(_, _, _))
2824 .WillOnce(DoAll(SetArgumentPointee<2>(kSuspendDelayId), Return(true)));
Daniel Erat0818cca2012-12-14 10:16:21 -08002825 EXPECT_CALL(power_manager, AddSuspendDelayCallback(_, _)).Times(1);
Darin Petkov3ec55342012-09-28 14:04:44 +02002826 manager()->AddTerminationAction(kKey1, base::Closure());
2827 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2828 manager()->AddTerminationAction(kKey2, base::Closure());
2829
2830 // Removing an action that ends up with a non-empty hook table should not
2831 // result in any calls to the power manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002832 EXPECT_CALL(power_manager, UnregisterSuspendDelay(_)).Times(0);
Darin Petkov3ec55342012-09-28 14:04:44 +02002833 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_)).Times(0);
2834 manager()->RemoveTerminationAction(kKey1);
2835 EXPECT_FALSE(GetTerminationActions()->IsEmpty());
2836 Mock::VerifyAndClearExpectations(&power_manager);
2837
2838 // Removing the last action should trigger unregistering from the power
2839 // manager.
Daniel Erat0818cca2012-12-14 10:16:21 -08002840 EXPECT_CALL(power_manager, UnregisterSuspendDelay(kSuspendDelayId))
2841 .WillOnce(Return(true));
Darin Petkov3ec55342012-09-28 14:04:44 +02002842 EXPECT_CALL(power_manager, RemoveSuspendDelayCallback(_));
2843 manager()->RemoveTerminationAction(kKey2);
2844 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
2845}
2846
2847TEST_F(ManagerTest, RunTerminationActions) {
2848 TerminationActionTest test_action;
2849 const string kActionName = "action";
2850
2851 EXPECT_CALL(test_action, Done(_));
2852 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2853 test_action.AsWeakPtr()));
2854
2855 manager()->AddTerminationAction(TerminationActionTest::kActionName,
2856 Bind(&TerminationActionTest::Action,
2857 test_action.AsWeakPtr()));
2858 test_action.set_manager(manager());
2859 EXPECT_CALL(test_action, Done(_));
2860 manager()->RunTerminationActions(Bind(&TerminationActionTest::Done,
2861 test_action.AsWeakPtr()));
2862}
2863
Daniel Erat0818cca2012-12-14 10:16:21 -08002864TEST_F(ManagerTest, OnSuspendImminent) {
2865 const int kSuspendId = 123;
Darin Petkov3ec55342012-09-28 14:04:44 +02002866 EXPECT_TRUE(GetTerminationActions()->IsEmpty());
Daniel Erat0818cca2012-12-14 10:16:21 -08002867 EXPECT_CALL(*power_manager_,
2868 ReportSuspendReadiness(
2869 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002870 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002871 OnSuspendImminent(kSuspendId);
Darin Petkov3ec55342012-09-28 14:04:44 +02002872}
2873
2874TEST_F(ManagerTest, OnSuspendActionsComplete) {
Daniel Erat0818cca2012-12-14 10:16:21 -08002875 const int kSuspendId = 54321;
Darin Petkov3ec55342012-09-28 14:04:44 +02002876 Error error;
Daniel Erat0818cca2012-12-14 10:16:21 -08002877 EXPECT_CALL(*power_manager_,
2878 ReportSuspendReadiness(
2879 manager()->suspend_delay_id_for_testing(), kSuspendId));
Darin Petkov3ec55342012-09-28 14:04:44 +02002880 SetPowerManager();
Daniel Erat0818cca2012-12-14 10:16:21 -08002881 OnSuspendActionsComplete(kSuspendId, error);
Darin Petkov3ec55342012-09-28 14:04:44 +02002882}
2883
Paul Stewartc681fa02012-03-02 19:40:04 -08002884TEST_F(ManagerTest, RecheckPortal) {
2885 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
2886 .WillOnce(Return(false));
2887 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
2888 .WillOnce(Return(true));
2889 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
2890 .Times(0);
2891
2892 manager()->RegisterDevice(mock_devices_[0]);
2893 manager()->RegisterDevice(mock_devices_[1]);
2894 manager()->RegisterDevice(mock_devices_[2]);
2895
2896 manager()->RecheckPortal(NULL);
2897}
2898
Paul Stewartd215af62012-04-24 23:25:50 -07002899TEST_F(ManagerTest, RecheckPortalOnService) {
2900 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
2901 dispatcher(),
2902 metrics(),
2903 manager());
2904 EXPECT_CALL(*mock_devices_[0].get(),
2905 IsConnectedToService(IsRefPtrTo(service)))
2906 .WillOnce(Return(false));
2907 EXPECT_CALL(*mock_devices_[1].get(),
2908 IsConnectedToService(IsRefPtrTo(service)))
2909 .WillOnce(Return(true));
2910 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
2911 .WillOnce(Return(true));
2912 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
2913 .Times(0);
2914
2915 manager()->RegisterDevice(mock_devices_[0]);
2916 manager()->RegisterDevice(mock_devices_[1]);
2917 manager()->RegisterDevice(mock_devices_[2]);
2918
2919 manager()->RecheckPortalOnService(service);
2920}
2921
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002922TEST_F(ManagerTest, GetDefaultService) {
2923 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002924 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002925
2926 scoped_refptr<MockService> mock_service(
2927 new NiceMock<MockService>(control_interface(),
2928 dispatcher(),
2929 metrics(),
2930 manager()));
2931
2932 manager()->RegisterService(mock_service);
2933 EXPECT_FALSE(manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002934 EXPECT_EQ("/", GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002935
2936 scoped_refptr<MockConnection> mock_connection(
2937 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07002938 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002939 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
Paul Stewart49739c02012-08-08 17:24:03 -07002940 EXPECT_EQ(mock_service->GetRpcIdentifier(), GetDefaultServiceRpcIdentifier());
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002941
Paul Stewartce4ec192012-03-14 12:53:46 -07002942 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07002943 manager()->DeregisterService(mock_service);
2944}
2945
Paul Stewart13ed2252012-03-21 12:52:46 -07002946TEST_F(ManagerTest, GetServiceWithGUID) {
2947 scoped_refptr<MockService> mock_service0(
2948 new NiceMock<MockService>(control_interface(),
2949 dispatcher(),
2950 metrics(),
2951 manager()));
2952
2953 scoped_refptr<MockService> mock_service1(
2954 new NiceMock<MockService>(control_interface(),
2955 dispatcher(),
2956 metrics(),
2957 manager()));
2958
Paul Stewartcb59fed2012-03-21 21:14:46 -07002959 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
2960 .Times(0);
2961 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
2962 .Times(0);
2963
Paul Stewart13ed2252012-03-21 12:52:46 -07002964 manager()->RegisterService(mock_service0);
2965 manager()->RegisterService(mock_service1);
2966
2967 const string kGUID0 = "GUID0";
2968 const string kGUID1 = "GUID1";
2969
2970 {
2971 Error error;
2972 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
2973 EXPECT_FALSE(error.IsSuccess());
2974 EXPECT_FALSE(service);
2975 }
2976
2977 KeyValueStore args;
2978 args.SetString(flimflam::kGuidProperty, kGUID1);
2979
2980 {
2981 Error error;
2982 ServiceRefPtr service = manager()->GetService(args, &error);
2983 EXPECT_EQ(Error::kInvalidArguments, error.type());
2984 EXPECT_FALSE(service);
2985 }
2986
2987 mock_service0->set_guid(kGUID0);
2988 mock_service1->set_guid(kGUID1);
2989
2990 {
2991 Error error;
2992 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
2993 EXPECT_TRUE(error.IsSuccess());
2994 EXPECT_EQ(mock_service0.get(), service.get());
2995 }
2996
2997 {
2998 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07002999 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
3000 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07003001 ServiceRefPtr service = manager()->GetService(args, &error);
3002 EXPECT_TRUE(error.IsSuccess());
3003 EXPECT_EQ(mock_service1.get(), service.get());
3004 }
3005
3006 manager()->DeregisterService(mock_service0);
3007 manager()->DeregisterService(mock_service1);
3008}
3009
Gary Morain028545d2012-04-07 14:55:52 -07003010
3011TEST_F(ManagerTest, CalculateStateOffline) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003012 EXPECT_FALSE(manager()->IsOnline());
3013 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3014
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003015 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003016 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003017 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3018 .Times(AnyNumber());
3019 scoped_refptr<MockService> mock_service0(
3020 new NiceMock<MockService>(control_interface(),
3021 dispatcher(),
3022 metrics(),
3023 manager()));
3024
3025 scoped_refptr<MockService> mock_service1(
3026 new NiceMock<MockService>(control_interface(),
3027 dispatcher(),
3028 metrics(),
3029 manager()));
3030
3031 EXPECT_CALL(*mock_service0.get(), IsConnected())
3032 .WillRepeatedly(Return(false));
3033 EXPECT_CALL(*mock_service1.get(), IsConnected())
3034 .WillRepeatedly(Return(false));
3035
3036 manager()->RegisterService(mock_service0);
3037 manager()->RegisterService(mock_service1);
3038
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003039 EXPECT_FALSE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003040 EXPECT_EQ("offline", manager()->CalculateState(NULL));
3041
3042 manager()->DeregisterService(mock_service0);
3043 manager()->DeregisterService(mock_service1);
3044}
3045
3046TEST_F(ManagerTest, CalculateStateOnline) {
Thieu Le6c1e3bb2013-02-06 15:20:35 -08003047 MockMetrics mock_metrics(dispatcher());
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003048 SetMetrics(&mock_metrics);
Gary Morain028545d2012-04-07 14:55:52 -07003049 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
3050 .Times(AnyNumber());
3051 scoped_refptr<MockService> mock_service0(
3052 new NiceMock<MockService>(control_interface(),
3053 dispatcher(),
3054 metrics(),
3055 manager()));
3056
3057 scoped_refptr<MockService> mock_service1(
3058 new NiceMock<MockService>(control_interface(),
3059 dispatcher(),
3060 metrics(),
3061 manager()));
3062
3063 EXPECT_CALL(*mock_service0.get(), IsConnected())
3064 .WillRepeatedly(Return(false));
3065 EXPECT_CALL(*mock_service1.get(), IsConnected())
3066 .WillRepeatedly(Return(true));
3067 EXPECT_CALL(*mock_service0.get(), state())
3068 .WillRepeatedly(Return(Service::kStateIdle));
3069 EXPECT_CALL(*mock_service1.get(), state())
3070 .WillRepeatedly(Return(Service::kStateConnected));
3071
3072 manager()->RegisterService(mock_service0);
3073 manager()->RegisterService(mock_service1);
Paul Stewartdfa46052012-06-26 09:44:14 -07003074 CompleteServiceSort();
Gary Morain028545d2012-04-07 14:55:52 -07003075
Darin Petkov4cbff5b2013-01-29 16:29:05 +01003076 EXPECT_TRUE(manager()->IsOnline());
Gary Morain028545d2012-04-07 14:55:52 -07003077 EXPECT_EQ("online", manager()->CalculateState(NULL));
3078
3079 manager()->DeregisterService(mock_service0);
3080 manager()->DeregisterService(mock_service1);
3081}
3082
Paul Stewart10e9e4e2012-04-26 19:46:28 -07003083TEST_F(ManagerTest, StartupPortalList) {
3084 // Simulate loading value from the default profile.
3085 const string kProfileValue("wifi,vpn");
3086 manager()->props_.check_portal_list = kProfileValue;
3087
3088 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
3089 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3090 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3091
3092 const string kStartupValue("cellular,ethernet");
3093 manager()->SetStartupPortalList(kStartupValue);
3094 // Ensure profile value is not overwritten, so when we save the default
3095 // profile, the correct value will still be written.
3096 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
3097
3098 // However we should read back a different list.
3099 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
3100 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
3101 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3102
3103 const string kRuntimeValue("ppp");
3104 // Setting a runtime value over the control API should overwrite both
3105 // the profile value and what we read back.
3106 Error error;
3107 manager()->mutable_store()->SetStringProperty(
3108 flimflam::kCheckPortalListProperty,
3109 kRuntimeValue,
3110 &error);
3111 ASSERT_TRUE(error.IsSuccess());
3112 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
3113 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
3114 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
3115 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
3116}
3117
Paul Stewart036dba02012-08-07 12:34:41 -07003118TEST_F(ManagerTest, LinkMonitorEnabled) {
3119 const string kEnabledTechnologies("wifi,vpn");
3120 manager()->props_.link_monitor_technologies = kEnabledTechnologies;
3121 EXPECT_TRUE(manager()->IsTechnologyLinkMonitorEnabled(Technology::kWifi));
3122 EXPECT_FALSE(
3123 manager()->IsTechnologyLinkMonitorEnabled(Technology::kCellular));
3124}
3125
Paul Stewart85aea152013-01-22 09:31:56 -08003126TEST_F(ManagerTest, IsDefaultProfile) {
Paul Stewart3c504012013-01-17 17:49:58 -08003127 EXPECT_TRUE(manager()->IsDefaultProfile(NULL));
Paul Stewart85aea152013-01-22 09:31:56 -08003128 scoped_ptr<MockStore> store0(new MockStore);
Paul Stewart3c504012013-01-17 17:49:58 -08003129 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
Paul Stewart85aea152013-01-22 09:31:56 -08003130 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08003131 new MockProfile(control_interface(), metrics(), manager(), ""));
Paul Stewart85aea152013-01-22 09:31:56 -08003132 EXPECT_CALL(*profile, GetConstStorage()).WillRepeatedly(Return(store0.get()));
3133 AdoptProfile(manager(), profile);
3134 EXPECT_TRUE(manager()->IsDefaultProfile(store0.get()));
3135 EXPECT_FALSE(manager()->IsDefaultProfile(NULL));
3136 scoped_ptr<MockStore> store1(new MockStore);
3137 EXPECT_FALSE(manager()->IsDefaultProfile(store1.get()));
3138}
3139
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003140TEST_F(ManagerTest, EnableTechnology) {
3141 Error error(Error::kOperationInitiated);
3142 ResultCallback callback;
3143 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3144 EXPECT_TRUE(error.IsSuccess());
3145
Joshua Krollda798622012-06-05 12:30:48 -07003146 ON_CALL(*mock_devices_[0], technology())
3147 .WillByDefault(Return(Technology::kEthernet));
Jason Glasgowdf7c5532012-05-14 14:41:45 -04003148
3149 manager()->RegisterDevice(mock_devices_[0]);
3150
3151 // Device is enabled, so expect operation is successful.
3152 mock_devices_[0]->enabled_ = true;
3153 error.Populate(Error::kOperationInitiated);
3154 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3155 EXPECT_TRUE(error.IsSuccess());
3156
3157 // Device is disabled, so expect operation in progress.
3158 mock_devices_[0]->enabled_ = false;
3159 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
3160 error.Populate(Error::kOperationInitiated);
3161 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
3162 EXPECT_TRUE(error.IsOngoing());
3163}
3164
3165TEST_F(ManagerTest, DisableTechnology) {
3166 Error error(Error::kOperationInitiated);
3167 ResultCallback callback;
3168 manager()->DisableTechnology(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 disabled, so expect operation is successful.
3177 error.Populate(Error::kOperationInitiated);
3178 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3179 EXPECT_TRUE(error.IsSuccess());
3180
3181 // Device is enabled, so expect operation in progress.
3182 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
3183 mock_devices_[0]->enabled_ = true;
3184 error.Populate(Error::kOperationInitiated);
3185 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
3186 EXPECT_TRUE(error.IsOngoing());
3187}
3188
Paul Stewart4d5efb72012-09-17 12:24:34 -07003189TEST_F(ManagerTest, IgnoredSearchList) {
3190 scoped_ptr<MockResolver> resolver(new StrictMock<MockResolver>());
3191 SetResolver(resolver.get());
3192 vector<string> ignored_paths;
3193 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3194 SetIgnoredDNSSearchPaths("");
3195 EXPECT_EQ("", GetIgnoredDNSSearchPaths());
3196
3197 const string kIgnored0 = "chromium.org";
3198 ignored_paths.push_back(kIgnored0);
3199 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3200 SetIgnoredDNSSearchPaths(kIgnored0);
3201 EXPECT_EQ(kIgnored0, GetIgnoredDNSSearchPaths());
3202
3203 const string kIgnored1 = "google.com";
3204 const string kIgnoredSum = kIgnored0 + "," + kIgnored1;
3205 ignored_paths.push_back(kIgnored1);
3206 EXPECT_CALL(*resolver.get(), set_ignored_search_list(ignored_paths));
3207 SetIgnoredDNSSearchPaths(kIgnoredSum);
3208 EXPECT_EQ(kIgnoredSum, GetIgnoredDNSSearchPaths());
3209
3210 SetResolver(Resolver::GetInstance());
3211}
3212
Paul Stewartbfb82552012-10-24 16:48:48 -07003213TEST_F(ManagerTest, ServiceStateChangeEmitsServices) {
3214 // Test to make sure that every service state-change causes the
3215 // Manager to emit a new service list.
3216 scoped_refptr<MockService> mock_service(
3217 new NiceMock<MockService>(control_interface(),
3218 dispatcher(),
3219 metrics(),
3220 manager()));
3221 EXPECT_CALL(*mock_service, state())
3222 .WillRepeatedly(Return(Service::kStateIdle));
3223
3224 manager()->RegisterService(mock_service);
3225 EXPECT_CALL(
3226 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3227 flimflam::kServicesProperty, _)).Times(1);
3228 EXPECT_CALL(
3229 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3230 flimflam::kServiceWatchListProperty, _)).Times(1);
3231 CompleteServiceSort();
3232
3233 Mock::VerifyAndClearExpectations(manager_adaptor_);
3234 EXPECT_CALL(
3235 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3236 flimflam::kServicesProperty, _)).Times(1);
3237 EXPECT_CALL(
3238 *manager_adaptor_, EmitRpcIdentifierArrayChanged(
3239 flimflam::kServiceWatchListProperty, _)).Times(1);
3240 manager()->UpdateService(mock_service.get());
3241 CompleteServiceSort();
3242
3243 manager()->DeregisterService(mock_service);
3244}
3245
3246TEST_F(ManagerTest, EnumerateServices) {
3247 scoped_refptr<MockService> mock_service(
3248 new NiceMock<MockService>(control_interface(),
3249 dispatcher(),
3250 metrics(),
3251 manager()));
3252 manager()->RegisterService(mock_service);
3253
3254 EXPECT_CALL(*mock_service, state())
3255 .WillRepeatedly(Return(Service::kStateConnected));
3256 EXPECT_CALL(*mock_service, IsVisible())
3257 .WillRepeatedly(Return(false));
3258 EXPECT_TRUE(EnumerateAvailableServices().empty());
3259 EXPECT_TRUE(EnumerateWatchedServices().empty());
3260
3261 EXPECT_CALL(*mock_service, state())
3262 .WillRepeatedly(Return(Service::kStateIdle));
3263 EXPECT_TRUE(EnumerateAvailableServices().empty());
3264 EXPECT_TRUE(EnumerateWatchedServices().empty());
3265
3266 EXPECT_CALL(*mock_service, IsVisible())
3267 .WillRepeatedly(Return(true));
3268 Service::ConnectState unwatched_states[] = {
3269 Service::kStateUnknown,
3270 Service::kStateIdle,
3271 Service::kStateFailure
3272 };
3273 for (size_t i = 0; i < arraysize(unwatched_states); ++i) {
3274 EXPECT_CALL(*mock_service, state())
3275 .WillRepeatedly(Return(unwatched_states[i]));
3276 EXPECT_FALSE(EnumerateAvailableServices().empty());
3277 EXPECT_TRUE(EnumerateWatchedServices().empty());
3278 }
3279
3280 Service::ConnectState watched_states[] = {
3281 Service::kStateAssociating,
3282 Service::kStateConfiguring,
3283 Service::kStateConnected,
3284 Service::kStateDisconnected,
3285 Service::kStatePortal,
3286 Service::kStateOnline
3287 };
3288 for (size_t i = 0; i < arraysize(watched_states); ++i) {
3289 EXPECT_CALL(*mock_service, state())
3290 .WillRepeatedly(Return(watched_states[i]));
3291 EXPECT_FALSE(EnumerateAvailableServices().empty());
3292 EXPECT_FALSE(EnumerateWatchedServices().empty());
3293 }
3294
3295 manager()->DeregisterService(mock_service);
3296}
3297
Paul Stewart39db5ca2013-03-18 14:15:17 -07003298TEST_F(ManagerTest, ConnectToBestServices) {
3299 scoped_refptr<MockService> wifi_service0(
3300 new NiceMock<MockService>(control_interface(),
3301 dispatcher(),
3302 metrics(),
3303 manager()));
3304 EXPECT_CALL(*wifi_service0.get(), state())
3305 .WillRepeatedly(Return(Service::kStateIdle));
3306 EXPECT_CALL(*wifi_service0.get(), IsConnected())
3307 .WillRepeatedly(Return(false));
3308 wifi_service0->set_connectable(true);
3309 wifi_service0->set_auto_connect(true);
3310 wifi_service0->SetSecurity(Service::kCryptoAes, true, true);
3311 EXPECT_CALL(*wifi_service0.get(), technology())
3312 .WillRepeatedly(Return(Technology::kWifi));
3313
3314 scoped_refptr<MockService> wifi_service1(
3315 new NiceMock<MockService>(control_interface(),
3316 dispatcher(),
3317 metrics(),
3318 manager()));
3319 EXPECT_CALL(*wifi_service1.get(), state())
3320 .WillRepeatedly(Return(Service::kStateIdle));
3321 EXPECT_CALL(*wifi_service1.get(), IsConnected())
3322 .WillRepeatedly(Return(false));
3323 wifi_service1->set_auto_connect(true);
3324 wifi_service1->set_connectable(true);
3325 wifi_service1->SetSecurity(Service::kCryptoRc4, true, true);
3326 EXPECT_CALL(*wifi_service1.get(), technology())
3327 .WillRepeatedly(Return(Technology::kWifi));
3328
3329 scoped_refptr<MockService> wifi_service2(
3330 new NiceMock<MockService>(control_interface(),
3331 dispatcher(),
3332 metrics(),
3333 manager()));
3334 EXPECT_CALL(*wifi_service2.get(), state())
3335 .WillRepeatedly(Return(Service::kStateConnected));
3336 EXPECT_CALL(*wifi_service2.get(), IsConnected())
3337 .WillRepeatedly(Return(true));
3338 wifi_service2->set_auto_connect(true);
3339 wifi_service2->set_connectable(true);
3340 wifi_service2->SetSecurity(Service::kCryptoNone, false, false);
3341 EXPECT_CALL(*wifi_service2.get(), technology())
3342 .WillRepeatedly(Return(Technology::kWifi));
3343
3344 manager()->RegisterService(wifi_service0);
3345 manager()->RegisterService(wifi_service1);
3346 manager()->RegisterService(wifi_service2);
3347
3348 CompleteServiceSort();
3349 EXPECT_TRUE(ServiceOrderIs(wifi_service2, wifi_service0));
3350
3351 scoped_refptr<MockService> cell_service(
3352 new NiceMock<MockService>(control_interface(),
3353 dispatcher(),
3354 metrics(),
3355 manager()));
3356
3357 EXPECT_CALL(*cell_service.get(), state())
3358 .WillRepeatedly(Return(Service::kStateConnected));
3359 EXPECT_CALL(*cell_service.get(), IsConnected())
3360 .WillRepeatedly(Return(true));
3361 wifi_service2->set_auto_connect(true);
3362 cell_service->set_connectable(true);
3363 EXPECT_CALL(*cell_service.get(), technology())
3364 .WillRepeatedly(Return(Technology::kCellular));
3365 manager()->RegisterService(cell_service);
3366
3367 scoped_refptr<MockService> vpn_service(
3368 new NiceMock<MockService>(control_interface(),
3369 dispatcher(),
3370 metrics(),
3371 manager()));
3372
3373 EXPECT_CALL(*vpn_service.get(), state())
3374 .WillRepeatedly(Return(Service::kStateIdle));
3375 EXPECT_CALL(*vpn_service.get(), IsConnected())
3376 .WillRepeatedly(Return(false));
3377 wifi_service2->set_auto_connect(false);
3378 vpn_service->set_connectable(true);
3379 EXPECT_CALL(*vpn_service.get(), technology())
3380 .WillRepeatedly(Return(Technology::kVPN));
3381 manager()->RegisterService(vpn_service);
3382
3383 // The connected services should be at the top.
3384 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3385
3386 EXPECT_CALL(*wifi_service0.get(), Connect(_)).Times(1);
3387 EXPECT_CALL(*wifi_service1.get(), Connect(_)).Times(0); // Lower priority.
3388 EXPECT_CALL(*wifi_service2.get(), Connect(_)).Times(0); // Lower priority.
3389 EXPECT_CALL(*cell_service.get(), Connect(_)).Times(0); // Already connected.
3390 EXPECT_CALL(*vpn_service.get(), Connect(_)).Times(0); // Not auto-connect.
3391
3392 manager()->ConnectToBestServices(NULL);
3393 dispatcher()->DispatchPendingEvents();
3394
3395 // After this operation, since the Connect calls above are mocked and
3396 // no actual state changes have occurred, we should expect that the
3397 // service sorting order will not have changed.
3398 EXPECT_TRUE(ServiceOrderIs(wifi_service2, cell_service));
3399}
3400
Christopher Wiley1057cd72013-02-28 15:21:29 -08003401TEST_F(ManagerTest, VerifyDestination) {
3402 const string kFakeCertificate("fake cert");
3403 const string kFakePublicKey("fake public key");
3404 const string kFakeNonce("fake public key");
3405 const string kFakeSignedData("fake signed data");
3406 const string kFakeUdn("fake udn");
3407 const char kSSIDStr[] = "fake ssid";
3408 const vector<uint8_t> kSSID(kSSIDStr, kSSIDStr + arraysize(kSSIDStr));
3409 const string kFakeData("muffin man");
3410 scoped_refptr<MockWiFiService> mock_destination(
3411 new NiceMock<MockWiFiService>(control_interface(),
3412 dispatcher(),
3413 metrics(),
3414 manager(),
3415 wifi_provider_,
3416 kSSID,
3417 "",
3418 "none",
3419 false));
3420 manager()->RegisterService(mock_destination);
3421 StrictMock<DestinationVerificationTest> dv_test;
3422
3423 // Verify that if we're not connected to anything, verification fails.
3424 {
3425 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3426 kFakePublicKey,
3427 kFakeNonce,
3428 kFakeSignedData,
3429 kFakeUdn,
3430 kSSID,
3431 _,
3432 _,
3433 _))
3434 .Times(0);
3435 Error error(Error::kOperationInitiated);
3436 ResultBoolCallback cb = Bind(
3437 &DestinationVerificationTest::ResultBoolCallbackStub,
3438 dv_test.AsWeakPtr());
3439 manager()->VerifyDestination(kFakeCertificate,
3440 kFakePublicKey,
3441 kFakeNonce,
3442 kFakeSignedData,
3443 kFakeUdn,
3444 cb,
3445 &error);
3446 EXPECT_TRUE(error.IsFailure());
3447 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3448 }
3449
3450 // Making the service look online will let service lookup in
3451 // VerifyDestinatoin succeed.
3452 EXPECT_CALL(*mock_destination.get(), IsConnected())
3453 .WillRepeatedly(Return(true));
3454
3455 // Lead off by verifying that the basic VerifyDestination flow works.
3456 {
3457 ResultBoolCallback passed_down_callback;
3458 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3459 kFakePublicKey,
3460 kFakeNonce,
3461 kFakeSignedData,
3462 kFakeUdn,
3463 kSSID,
3464 _,
3465 _,
3466 _))
3467 .Times(1)
3468 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3469 // Ask the manager to verify the current destination. This should look
3470 // up our previously registered service, and pass some metadata about
3471 // that service down to the CryptoUtilProxy to verify.
3472 Error error(Error::kOperationInitiated);
3473 ResultBoolCallback cb = Bind(
3474 &DestinationVerificationTest::ResultBoolCallbackStub,
3475 dv_test.AsWeakPtr());
3476 manager()->VerifyDestination(kFakeCertificate,
3477 kFakePublicKey,
3478 kFakeNonce,
3479 kFakeSignedData,
3480 kFakeUdn,
3481 cb,
3482 &error);
3483 // We assert here, because if the operation is not ongoing, it is
3484 // inconsistent with shim behavior to call the callback anyway.
3485 ASSERT_TRUE(error.IsOngoing());
3486 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3487 EXPECT_CALL(dv_test, ResultBoolCallbackStub(_, true)).Times(1);
3488 // Call the callback passed into the CryptoUtilProxy, which
3489 // should find its way into the callback passed into the manager.
3490 // In real code, that callback passed into the manager is from the
3491 // DBus adaptor.
3492 Error e;
3493 passed_down_callback.Run(e, true);
3494 Mock::VerifyAndClearExpectations(&dv_test);
3495 }
3496
3497 // Now for a slightly more complex variant. When we encrypt data,
3498 // we do the same verification step but monkey with the callback to
3499 // link ourselves to an encrypt step afterward.
3500 {
3501 ResultBoolCallback passed_down_callback;
3502 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3503 kFakePublicKey,
3504 kFakeNonce,
3505 kFakeSignedData,
3506 kFakeUdn,
3507 kSSID,
3508 _,
3509 _,
3510 _))
3511 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3512
3513 Error error(Error::kOperationInitiated);
3514 ResultStringCallback cb = Bind(
3515 &DestinationVerificationTest::ResultStringCallbackStub,
3516 dv_test.AsWeakPtr());
3517 manager()->VerifyAndEncryptData(kFakeCertificate,
3518 kFakePublicKey,
3519 kFakeNonce,
3520 kFakeSignedData,
3521 kFakeUdn,
3522 kFakeData,
3523 cb,
3524 &error);
3525 ASSERT_TRUE(error.IsOngoing());
3526 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3527 // Now, if we call that passed down callback, we should see encrypt being
3528 // called.
3529 ResultStringCallback second_passed_down_callback;
3530 EXPECT_CALL(*crypto_util_proxy_, EncryptData(kFakePublicKey,
3531 kFakeData,
3532 _,
3533 _))
3534 .Times(1)
3535 .WillOnce(DoAll(SaveArg<2>(&second_passed_down_callback),
3536 Return(true)));
3537 Error e;
3538 passed_down_callback.Run(e, true);
3539 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3540 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, _)).Times(1);
3541 // And if we call the second passed down callback, we should see the
3542 // original function we passed down to VerifyDestination getting called.
3543 e.Reset();
3544 second_passed_down_callback.Run(e, "");
3545 Mock::VerifyAndClearExpectations(&dv_test);
3546 }
3547
3548 // If verification fails on the way to trying to encrypt, we should ditch
3549 // without calling encrypt at all.
3550 {
3551 ResultBoolCallback passed_down_callback;
3552 EXPECT_CALL(*crypto_util_proxy_, VerifyDestination(kFakeCertificate,
3553 kFakePublicKey,
3554 kFakeNonce,
3555 kFakeSignedData,
3556 kFakeUdn,
3557 kSSID,
3558 _,
3559 _,
3560 _))
3561 .WillOnce(DoAll(SaveArg<7>(&passed_down_callback), Return(true)));
3562
3563 Error error(Error::kOperationInitiated);
3564 ResultStringCallback cb = Bind(
3565 &DestinationVerificationTest::ResultStringCallbackStub,
3566 dv_test.AsWeakPtr());
3567 manager()->VerifyAndEncryptData(kFakeCertificate,
3568 kFakePublicKey,
3569 kFakeNonce,
3570 kFakeSignedData,
3571 kFakeUdn,
3572 kFakeData,
3573 cb,
3574 &error);
3575 ASSERT_TRUE(error.IsOngoing());
3576 Mock::VerifyAndClearExpectations(crypto_util_proxy_);
3577 Error e(Error::kOperationFailed);
3578 EXPECT_CALL(*crypto_util_proxy_, EncryptData(_, _, _, _)).Times(0);
3579 // Although we're ditching, this callback is what cleans up the pending
3580 // DBus call.
3581 EXPECT_CALL(dv_test, ResultStringCallbackStub(_, string(""))).Times(1);
3582 passed_down_callback.Run(e, false);
3583 Mock::VerifyAndClearExpectations(&dv_test);
3584 }
3585}
3586
Paul Stewartd2e1c362013-03-03 19:06:07 -08003587TEST_F(ManagerTest, IsProfileBefore) {
3588 scoped_refptr<MockProfile> profile0(
3589 new NiceMock<MockProfile>(
3590 control_interface(), metrics(), manager(), ""));
3591 scoped_refptr<MockProfile> profile1(
3592 new NiceMock<MockProfile>(
3593 control_interface(), metrics(), manager(), ""));
3594
3595 AdoptProfile(manager(), profile0);
3596 AdoptProfile(manager(), profile1); // profile1 is after profile0.
3597 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile1));
3598 EXPECT_FALSE(manager()->IsProfileBefore(profile1, profile0));
3599
3600 // A few abnormal cases, but it's good to track their behavior.
3601 scoped_refptr<MockProfile> profile2(
3602 new NiceMock<MockProfile>(
3603 control_interface(), metrics(), manager(), ""));
3604 EXPECT_TRUE(manager()->IsProfileBefore(profile0, profile2));
3605 EXPECT_TRUE(manager()->IsProfileBefore(profile1, profile2));
3606 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile0));
3607 EXPECT_FALSE(manager()->IsProfileBefore(profile2, profile1));
3608}
3609
Chris Masone9be4a9d2011-05-16 15:44:09 -07003610} // namespace shill