blob: 3e1dd591e232ad76acec2877df9aff632dc186f1 [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>
Chris Masone9be4a9d2011-05-16 15:44:09 -070013#include <base/logging.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/scoped_temp_dir.h>
15#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070016#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070018#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070019#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070020
mukesh agrawal32399322011-09-01 10:53:43 -070021#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070022#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070023#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070024#include "shill/glib.h"
25#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070026#include "shill/key_value_store.h"
mukesh 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"
Chris Masone9be4a9d2011-05-16 15:44:09 -070030#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080031#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070032#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000033#include "shill/mock_metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070034#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070035#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070036#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070037#include "shill/mock_wifi.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070038#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070040#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070041#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042
43using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070044using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070045using std::string;
46using std::vector;
47
Chris Masone9be4a9d2011-05-16 15:44:09 -070048namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070049using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070050using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080051using ::testing::ContainerEq;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070052using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070053using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070054using ::testing::NiceMock;
55using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070056using ::testing::ReturnRef;
Gaurav Shah435de2c2011-11-17 19:01:07 -080057using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080058using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070059using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070060
Chris Masone3bd3c8c2011-06-13 08:20:26 -070061class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070062 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070063 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070064 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070065 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080066 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070067 manager(),
68 "wifi0",
69 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080070 4)),
71 device_info_(new NiceMock<MockDeviceInfo>(
72 control_interface(),
73 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080074 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080075 reinterpret_cast<Manager*>(NULL))),
76 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070077 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
78 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080079 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070080 manager(),
81 "null0",
82 "addr0",
83 0));
84 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
85 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080086 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070087 manager(),
88 "null1",
89 "addr1",
90 1));
91 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
92 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080093 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070094 manager(),
95 "null2",
96 "addr2",
97 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080098 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
99 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800100 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800101 manager(),
102 "null3",
103 "addr3",
104 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700105 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800106
107 // Replace the manager's adaptor with a quieter one, and one
108 // we can do EXPECT*() against. Passes ownership.
109 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700110 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700111 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700112
Paul Stewartfdd16072011-09-16 12:41:35 -0700113 bool IsDeviceRegistered(const DeviceRefPtr &device,
114 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700115 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700116 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700117 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700118 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700119 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700120
Paul Stewarta849a3d2011-11-03 05:54:09 -0700121 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
122 manager->profiles_.push_back(profile);
123 }
124
Paul Stewart75225512012-01-26 22:51:33 -0800125 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
126 return manager->ephemeral_profile_;
127 }
128
Chris Masone6515aab2011-10-12 16:19:09 -0700129 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
130 Profile::Identifier id("rather", "irrelevant");
131 scoped_ptr<Profile> profile(new Profile(control_interface(),
132 manager,
133 id,
134 "",
135 false));
136 FilePath final_path(storage_path());
137 final_path = final_path.Append("test.profile");
138 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
139 storage->set_path(final_path);
140 if (!storage->Open())
141 return NULL;
142 profile->set_storage(storage.release()); // Passes ownership.
143 return profile.release();
144 }
145
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700146 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
147 const string &profile_identifier,
148 const string &service_name) {
149 GLib glib;
150 KeyFileStore store(&glib);
151 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
152 return store.Open() &&
153 store.SetString(service_name, "rather", "irrelevant") &&
154 store.Close();
155 }
156
157 Error::Type TestCreateProfile(Manager *manager, const string &name) {
158 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800159 string path;
160 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700161 return error.type();
162 }
163
164 Error::Type TestPopAnyProfile(Manager *manager) {
165 Error error;
166 manager->PopAnyProfile(&error);
167 return error.type();
168 }
169
170 Error::Type TestPopProfile(Manager *manager, const string &name) {
171 Error error;
172 manager->PopProfile(name, &error);
173 return error.type();
174 }
175
176 Error::Type TestPushProfile(Manager *manager, const string &name) {
177 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800178 string path;
179 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700180 return error.type();
181 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000182
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700183 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000184 typedef scoped_refptr<MockService> MockServiceRefPtr;
185
186 MockServiceRefPtr MakeAutoConnectableService() {
187 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
188 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800189 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000190 manager());
191 service->MakeFavorite();
192 service->set_connectable(true);
193 return service;
194 }
195
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700196 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700197 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800198 scoped_ptr<MockDeviceInfo> device_info_;
199
200 // This pointer is owned by the manager, and only tracked here for EXPECT*()
201 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700202};
203
Paul Stewart22aa71b2011-09-16 12:15:11 -0700204bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
205 return (svc0.get() == manager()->services_[0].get() &&
206 svc1.get() == manager()->services_[1].get());
207}
208
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700209TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700210 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
211 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700212}
213
Chris Masone9be4a9d2011-05-16 15:44:09 -0700214TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700215 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700216 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700217 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700218 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700219 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700220 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700221
Paul Stewart22aa71b2011-09-16 12:15:11 -0700222 manager()->RegisterDevice(mock_devices_[0]);
223 manager()->RegisterDevice(mock_devices_[1]);
224 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700225
Paul Stewart22aa71b2011-09-16 12:15:11 -0700226 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
227 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
228 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700229}
230
Paul Stewarta41e38d2011-11-11 07:47:29 -0800231TEST_F(ManagerTest, DeviceRegistrationAndStart) {
232 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500233 mock_devices_[0]->enabled_persistent_ = true;
234 mock_devices_[1]->enabled_persistent_ = false;
235 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800236 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500237 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800238 .Times(0);
239 manager()->RegisterDevice(mock_devices_[0]);
240 manager()->RegisterDevice(mock_devices_[1]);
241}
242
243TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
244 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
245 DeviceRefPtr device_ref(mock_devices_[0].get());
246 AdoptProfile(manager(), profile); // Passes ownership.
247 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
248 EXPECT_CALL(*profile, Save());
249 manager()->RegisterDevice(mock_devices_[0]);
250}
251
Chris Masone9be4a9d2011-05-16 15:44:09 -0700252TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700253 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700254 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700255 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700256 .WillByDefault(Return(true));
257
Gaurav Shah435de2c2011-11-17 19:01:07 -0800258 manager()->RegisterDevice(mock_devices_[0]);
259 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700260
Paul Stewart22aa71b2011-09-16 12:15:11 -0700261 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
262 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700263
Eric Shienbrood9a245532012-03-07 14:20:39 -0500264 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800265 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700266 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700267
Eric Shienbrood9a245532012-03-07 14:20:39 -0500268 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800269 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700270 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700271}
272
273TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700274 // It's much easier and safer to use a real GLib for this test.
275 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700276 Manager manager(control_interface(),
277 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800278 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700279 &glib,
280 run_path(),
281 storage_path(),
282 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700283 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
284 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700285 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700286
Chris Masone9be4a9d2011-05-16 15:44:09 -0700287 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700288 new NiceMock<MockService>(control_interface(),
289 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800290 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700291 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700292 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700293 new NiceMock<MockService>(control_interface(),
294 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800295 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700296 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700297
mukesh agrawal51a7e932011-07-27 16:18:26 -0700298 string service1_name(mock_service->UniqueName());
299 string service2_name(mock_service2->UniqueName());
300
301 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
302 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700303 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700304 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700305 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700306 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700307 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700308
Chris Masone9d779932011-08-25 16:33:41 -0700309 manager.RegisterService(mock_service);
310 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700311
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800312 Error error;
313 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700314 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700315 EXPECT_EQ(2, ids.size());
316 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
317 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700318
Chris Masone9d779932011-08-25 16:33:41 -0700319 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
320 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
321
322 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700323}
324
Chris Masone6515aab2011-10-12 16:19:09 -0700325TEST_F(ManagerTest, RegisterKnownService) {
326 // It's much easier and safer to use a real GLib for this test.
327 GLib glib;
328 Manager manager(control_interface(),
329 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800330 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700331 &glib,
332 run_path(),
333 storage_path(),
334 string());
335 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
336 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700337 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700338 {
339 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
340 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800341 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700342 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700343 ASSERT_TRUE(profile->AdoptService(service1));
344 ASSERT_TRUE(profile->ContainsService(service1));
345 } // Force destruction of service1.
346
347 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
348 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800349 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700350 &manager));
351 manager.RegisterService(service2);
352 EXPECT_EQ(service2->profile().get(), profile.get());
353 manager.Stop();
354}
355
356TEST_F(ManagerTest, RegisterUnknownService) {
357 // It's much easier and safer to use a real GLib for this test.
358 GLib glib;
359 Manager manager(control_interface(),
360 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800361 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700362 &glib,
363 run_path(),
364 storage_path(),
365 string());
366 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
367 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700368 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700369 {
370 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
371 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800372 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700373 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700374 ASSERT_TRUE(profile->AdoptService(service1));
375 ASSERT_TRUE(profile->ContainsService(service1));
376 } // Force destruction of service1.
377 scoped_refptr<MockService> mock_service2(
378 new NiceMock<MockService>(control_interface(),
379 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800380 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700381 &manager));
382 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
383 .WillRepeatedly(Return(mock_service2->UniqueName()));
384 manager.RegisterService(mock_service2);
385 EXPECT_NE(mock_service2->profile().get(), profile.get());
386 manager.Stop();
387}
388
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000389TEST_F(ManagerTest, DeregisterUnregisteredService) {
390 // WiFi assumes that it can deregister a service that is not
391 // registered. (E.g. a hidden service can be deregistered when it
392 // loses its last endpoint, and again when WiFi is Stop()-ed.)
393 //
394 // So test that doing so doesn't cause a crash.
395 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
396 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800397 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000398 manager());
399 manager()->DeregisterService(service);
400}
401
Chris Masonea8a2c252011-06-27 22:16:30 -0700402TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700403 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700404 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700405 map<string, ::DBus::Variant> props;
406 Error error(Error::kInvalidProperty, "");
407 {
408 ::DBus::Error dbus_error;
409 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700410 manager()->mutable_store()->SetStringProperty(
411 flimflam::kCheckPortalListProperty,
412 expected,
413 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700414 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700415 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
416 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
417 expected);
418 }
419 {
420 ::DBus::Error dbus_error;
421 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700422 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
423 expected,
424 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700425 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700426 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
427 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
428 expected);
429 }
430}
431
Chris Masone3c3f6a12011-07-01 10:01:41 -0700432TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700433 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700434 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800435 manager()->RegisterDevice(mock_devices_[0]);
436 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700437 {
438 map<string, ::DBus::Variant> props;
439 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700440 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700441 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
442 Strings devices =
443 props[flimflam::kDevicesProperty].operator vector<string>();
444 EXPECT_EQ(2, devices.size());
445 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700446}
447
mukesh agrawal2366eed2012-03-20 18:21:50 -0700448TEST_F(ManagerTest, GetServicesProperty) {
449 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
450 AdoptProfile(manager(), profile);
451 map<string, ::DBus::Variant> props;
452 ::DBus::Error dbus_error;
453 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
454 map<string, ::DBus::Variant>::const_iterator prop =
455 props.find(flimflam::kServicesProperty);
456 ASSERT_FALSE(prop == props.end());
457 const ::DBus::Variant &variant = prop->second;
458 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
459}
460
Chris Masone6791a432011-07-12 13:23:19 -0700461TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700462 Manager manager(control_interface(),
463 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800464 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700465 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700466 run_path(),
467 storage_path(),
468 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700469 scoped_refptr<MockService> s2(new MockService(control_interface(),
470 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800471 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700472 &manager));
473 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700474 {
Chris Masone6515aab2011-10-12 16:19:09 -0700475 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700476 ProfileRefPtr profile(
477 new Profile(control_interface(), &manager, id, "", false));
478 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700479 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700480 .WillRepeatedly(Return(true));
481 EXPECT_CALL(*storage, Flush())
482 .Times(AnyNumber())
483 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700484 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700485 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700486 }
Chris Masone6515aab2011-10-12 16:19:09 -0700487 // Create a profile that already has |s2| in it.
488 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700489 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700490
Chris Masone6515aab2011-10-12 16:19:09 -0700491 // Now, move the Service |s2| to another profile.
492 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
493 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700494
495 // Force destruction of the original Profile, to ensure that the Service
496 // is kept alive and populated with data.
497 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700498 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700499 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700500}
501
Paul Stewart7f61e522012-03-22 11:13:45 -0700502TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
503 scoped_refptr<MockProfile> mock_profile(
504 new MockProfile(control_interface(), manager(), ""));
505 const string kProfileName("profile0");
506 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
507 .WillRepeatedly(Return(kProfileName));
508 AdoptProfile(manager(), mock_profile);
509
510 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
511 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
512 EXPECT_EQ(mock_profile.get(), profile.get());
513}
514
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800515TEST_F(ManagerTest, SetProfileForService) {
516 scoped_refptr<MockProfile> profile0(
517 new MockProfile(control_interface(), manager(), ""));
518 string profile_name0("profile0");
519 EXPECT_CALL(*profile0, GetRpcIdentifier())
520 .WillRepeatedly(Return(profile_name0));
521 AdoptProfile(manager(), profile0);
522 scoped_refptr<MockService> service(new MockService(control_interface(),
523 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800524 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800525 manager()));
526 service->set_profile(profile0);
527
528 {
529 Error error;
530 manager()->SetProfileForService(service, "foo", &error);
531 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700532 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800533 }
534
535 {
536 Error error;
537 manager()->SetProfileForService(service, profile_name0, &error);
538 EXPECT_EQ(Error::kInvalidArguments, error.type());
539 EXPECT_EQ("Service is already connected to this profile", error.message());
540 }
541
542 scoped_refptr<MockProfile> profile1(
543 new MockProfile(control_interface(), manager(), ""));
544 string profile_name1("profile1");
545 EXPECT_CALL(*profile1, GetRpcIdentifier())
546 .WillRepeatedly(Return(profile_name1));
547 AdoptProfile(manager(), profile1);
548
549 {
550 Error error;
551 EXPECT_CALL(*profile1, AdoptService(_))
552 .WillOnce(Return(true));
553 EXPECT_CALL(*profile0, AbandonService(_))
554 .WillOnce(Return(true));
555 manager()->SetProfileForService(service, profile_name1, &error);
556 EXPECT_TRUE(error.IsSuccess());
557 }
558}
559
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700560TEST_F(ManagerTest, CreateProfile) {
561 // It's much easier to use real Glib here since we want the storage
562 // side-effects.
563 GLib glib;
564 ScopedTempDir temp_dir;
565 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
566
567 Manager manager(control_interface(),
568 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800569 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700570 &glib,
571 run_path(),
572 storage_path(),
573 temp_dir.path().value());
574
575 // Invalid name should be rejected.
576 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
577
Paul Stewartd0a3b812012-03-28 22:48:22 -0700578 // A profile with invalid characters in it should similarly be rejected.
579 EXPECT_EQ(Error::kInvalidArguments,
580 TestCreateProfile(&manager, "valid_profile"));
581
582 // We should be able to create a machine profile.
583 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700584
Gary Morainb672d352012-04-25 09:19:06 -0700585 // We should succeed in creating a valid user profile. Verify the returned
586 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700587 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700588 {
589 Error error;
590 string path;
591 manager.CreateProfile(kProfile, &path, &error);
592 EXPECT_EQ(Error::kSuccess, error.type());
593 EXPECT_EQ("/profile_rpc", path);
594 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700595
596 // We should fail in creating it a second time (already exists).
597 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
598}
599
600TEST_F(ManagerTest, PushPopProfile) {
601 // It's much easier to use real Glib in creating a Manager for this
602 // test here since we want the storage side-effects.
603 GLib glib;
604 ScopedTempDir temp_dir;
605 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
606 Manager manager(control_interface(),
607 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800608 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700609 &glib,
610 run_path(),
611 storage_path(),
612 temp_dir.path().value());
613
614 // Pushing an invalid profile should fail.
615 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
616
Paul Stewartd0a3b812012-03-28 22:48:22 -0700617 // Pushing a default profile that does not exist should fail.
618 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700619
620 const char kProfile0[] = "~user/profile0";
621 const char kProfile1[] = "~user/profile1";
622
623 // Create a couple of profiles.
624 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
625 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
626
627 // Push these profiles on the stack.
628 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
629 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
630
631 // Pushing a profile a second time should fail.
632 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
633 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
634
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800635 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700636 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800637 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700638
639 // Make sure a profile name that doesn't exist fails.
640 const char kProfile2Id[] = "profile2";
641 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
642 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
643
644 // Create a new service, with a specific storage name.
645 scoped_refptr<MockService> service(
646 new NiceMock<MockService>(control_interface(),
647 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800648 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700649 &manager));
650 const char kServiceName[] = "service_storage_name";
651 EXPECT_CALL(*service.get(), GetStorageIdentifier())
652 .WillRepeatedly(Return(kServiceName));
653 EXPECT_CALL(*service.get(), Load(_))
654 .WillRepeatedly(Return(true));
655
656 // Add this service to the manager -- it should end up in the ephemeral
657 // profile.
658 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800659 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700660
661 // Create storage for a profile that contains the service storage name.
662 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
663 kServiceName));
664
665 // When we push the profile, the service should move away from the
666 // ephemeral profile to this new profile since it has an entry for
667 // this service.
668 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800669 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700670 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
671
672 // Insert another profile that should supersede ownership of the service.
673 const char kProfile3Id[] = "profile3";
674 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
675 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
676 kServiceName));
677 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
678 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
679
680 // Popping an invalid profile name should fail.
681 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
682
683 // Popping an profile that is not at the top of the stack should fail.
684 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
685
686 // Popping the top profile should succeed.
687 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
688
689 // Moreover the service should have switched profiles to profile 2.
690 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
691
692 // Popping the top profile should succeed.
693 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
694
695 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800696 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700697
698 // Pop the remaining two services off the stack.
699 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
700 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
701
702 // Next pop should fail with "stack is empty".
703 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700704
705 const char kMachineProfile0[] = "machineprofile0";
706 const char kMachineProfile1[] = "machineprofile1";
707 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
708 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
709
710 // Should be able to push a machine profile.
711 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
712
713 // Should be able to push a user profile atop a machine profile.
714 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
715
716 // Pushing a system-wide profile on top of a user profile should fail.
717 EXPECT_EQ(Error::kInvalidArguments,
718 TestPushProfile(&manager, kMachineProfile1));
719
720 // However if we pop the user profile, we should be able stack another
721 // machine profile on.
722 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
723 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700724}
725
Paul Stewarte73d05c2012-03-29 16:26:05 -0700726TEST_F(ManagerTest, RemoveProfile) {
727 // It's much easier to use real Glib in creating a Manager for this
728 // test here since we want the storage side-effects.
729 GLib glib;
730 ScopedTempDir temp_dir;
731 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
732 Manager manager(control_interface(),
733 dispatcher(),
734 metrics(),
735 &glib,
736 run_path(),
737 storage_path(),
738 temp_dir.path().value());
739
740 const char kProfile0[] = "profile0";
741 FilePath profile_path(
742 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
743
744 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
745 ASSERT_TRUE(file_util::PathExists(profile_path));
746
747 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
748
749 // Remove should fail since the profile is still on the stack.
750 {
751 Error error;
752 manager.RemoveProfile(kProfile0, &error);
753 EXPECT_EQ(Error::kInvalidArguments, error.type());
754 }
755
756 // Profile path should still exist.
757 EXPECT_TRUE(file_util::PathExists(profile_path));
758
759 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
760
761 // This should succeed now that the profile is off the stack.
762 {
763 Error error;
764 manager.RemoveProfile(kProfile0, &error);
765 EXPECT_EQ(Error::kSuccess, error.type());
766 }
767
768 // Profile path should no longer exist.
769 EXPECT_FALSE(file_util::PathExists(profile_path));
770
771 // Another remove succeeds, due to a foible in file_util::Delete --
772 // it is not an error to delete a file that does not exist.
773 {
774 Error error;
775 manager.RemoveProfile(kProfile0, &error);
776 EXPECT_EQ(Error::kSuccess, error.type());
777 }
778
779 // Let's create an error case that will "work". Create a non-empty
780 // directory in the place of the profile pathname.
781 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
782 {
783 Error error;
784 manager.RemoveProfile(kProfile0, &error);
785 EXPECT_EQ(Error::kOperationFailed, error.type());
786 }
787}
788
Paul Stewart75225512012-01-26 22:51:33 -0800789// Use this matcher instead of passing RefPtrs directly into the arguments
790// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
791// system teardown.
792MATCHER_P(IsRefPtrTo, ref_address, "") {
793 return arg.get() == ref_address;
794}
795
796TEST_F(ManagerTest, HandleProfileEntryDeletion) {
797 MockServiceRefPtr s_not_in_profile(
798 new NiceMock<MockService>(control_interface(),
799 dispatcher(),
800 metrics(),
801 manager()));
802 MockServiceRefPtr s_not_in_group(
803 new NiceMock<MockService>(control_interface(),
804 dispatcher(),
805 metrics(),
806 manager()));
807 MockServiceRefPtr s_configure_fail(
808 new NiceMock<MockService>(control_interface(),
809 dispatcher(),
810 metrics(),
811 manager()));
812 MockServiceRefPtr s_configure_succeed(
813 new NiceMock<MockService>(control_interface(),
814 dispatcher(),
815 metrics(),
816 manager()));
817
818 string entry_name("entry_name");
819 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
820 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
821 .WillRepeatedly(Return("not_entry_name"));
822 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
823 .WillRepeatedly(Return(entry_name));
824 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
825 .WillRepeatedly(Return(entry_name));
826
827 manager()->RegisterService(s_not_in_profile);
828 manager()->RegisterService(s_not_in_group);
829 manager()->RegisterService(s_configure_fail);
830 manager()->RegisterService(s_configure_succeed);
831
832 scoped_refptr<MockProfile> profile0(
833 new StrictMock<MockProfile>(control_interface(), manager(), ""));
834 scoped_refptr<MockProfile> profile1(
835 new StrictMock<MockProfile>(control_interface(), manager(), ""));
836
837 s_not_in_group->set_profile(profile1);
838 s_configure_fail->set_profile(profile1);
839 s_configure_succeed->set_profile(profile1);
840
841 AdoptProfile(manager(), profile0);
842 AdoptProfile(manager(), profile1);
843
844 // No services are a member of this profile.
845 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
846
847 // No services that are members of this profile have this entry name.
848 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
849
850 // Only services that are members of the profile and group will be abandoned.
851 EXPECT_CALL(*profile1.get(),
852 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
853 EXPECT_CALL(*profile1.get(),
854 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
855 EXPECT_CALL(*profile1.get(),
856 AbandonService(IsRefPtrTo(s_configure_fail.get())))
857 .WillOnce(Return(true));
858 EXPECT_CALL(*profile1.get(),
859 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
860 .WillOnce(Return(true));
861
862 // Never allow services to re-join profile1.
863 EXPECT_CALL(*profile1.get(), ConfigureService(_))
864 .WillRepeatedly(Return(false));
865
866 // Only allow one of the members of the profile and group to successfully
867 // join profile0.
868 EXPECT_CALL(*profile0.get(),
869 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
870 EXPECT_CALL(*profile0.get(),
871 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
872 EXPECT_CALL(*profile0.get(),
873 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
874 .WillOnce(Return(false));
875 EXPECT_CALL(*profile0.get(),
876 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
877 .WillOnce(Return(true));
878
879 // Expect the failed-to-configure service to have Unload() called on it.
880 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
881 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
882 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
883 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
884
885 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
886
887 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
888 EXPECT_EQ(profile1, s_not_in_group->profile());
889 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
890
891 // Since we are using a MockProfile, the profile does not actually change,
892 // since ConfigureService was not actually called on the service.
893 EXPECT_EQ(profile1, s_configure_succeed->profile());
894}
895
Paul Stewart65512e12012-03-26 18:01:08 -0700896TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
897 MockServiceRefPtr s_will_remove0(
898 new NiceMock<MockService>(control_interface(),
899 dispatcher(),
900 metrics(),
901 manager()));
902 MockServiceRefPtr s_will_remove1(
903 new NiceMock<MockService>(control_interface(),
904 dispatcher(),
905 metrics(),
906 manager()));
907 MockServiceRefPtr s_will_not_remove0(
908 new NiceMock<MockService>(control_interface(),
909 dispatcher(),
910 metrics(),
911 manager()));
912 MockServiceRefPtr s_will_not_remove1(
913 new NiceMock<MockService>(control_interface(),
914 dispatcher(),
915 metrics(),
916 manager()));
917
918 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
919 .Times(4); // Once for each registration.
920
921 string entry_name("entry_name");
922 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
923 .WillRepeatedly(Return(entry_name));
924 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
925 .WillRepeatedly(Return(entry_name));
926 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
927 .WillRepeatedly(Return(entry_name));
928 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
929 .WillRepeatedly(Return(entry_name));
930
931 manager()->RegisterService(s_will_remove0);
932 manager()->RegisterService(s_will_not_remove0);
933 manager()->RegisterService(s_will_remove1);
934 manager()->RegisterService(s_will_not_remove1);
935
936 // One for each service added above.
937 ASSERT_EQ(4, manager()->services_.size());
938
939 scoped_refptr<MockProfile> profile(
940 new StrictMock<MockProfile>(control_interface(), manager(), ""));
941
942 s_will_remove0->set_profile(profile);
943 s_will_remove1->set_profile(profile);
944 s_will_not_remove0->set_profile(profile);
945 s_will_not_remove1->set_profile(profile);
946
947 AdoptProfile(manager(), profile);
948
949 // Deny any of the services re-entry to the profile.
950 EXPECT_CALL(*profile, ConfigureService(_))
951 .WillRepeatedly(Return(false));
952
953 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
954 .WillOnce(Return(true));
955 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
956 .WillOnce(Return(true));
957 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
958 .WillOnce(Return(true));
959 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
960 .WillOnce(Return(true));
961
962 EXPECT_CALL(*s_will_remove0, Unload())
963 .WillOnce(Return(true));
964 EXPECT_CALL(*s_will_remove1, Unload())
965 .WillOnce(Return(true));
966 EXPECT_CALL(*s_will_not_remove0, Unload())
967 .WillOnce(Return(false));
968 EXPECT_CALL(*s_will_not_remove1, Unload())
969 .WillOnce(Return(false));
970
971
972 // This will cause all the profiles to be unloaded.
973 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
974
975 // 2 of the 4 services added above should have been unregistered and
976 // removed, leaving 2.
977 EXPECT_EQ(2, manager()->services_.size());
978 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
979 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
980}
981
982TEST_F(ManagerTest, PopProfileWithUnload) {
983 MockServiceRefPtr s_will_remove0(
984 new NiceMock<MockService>(control_interface(),
985 dispatcher(),
986 metrics(),
987 manager()));
988 MockServiceRefPtr s_will_remove1(
989 new NiceMock<MockService>(control_interface(),
990 dispatcher(),
991 metrics(),
992 manager()));
993 MockServiceRefPtr s_will_not_remove0(
994 new NiceMock<MockService>(control_interface(),
995 dispatcher(),
996 metrics(),
997 manager()));
998 MockServiceRefPtr s_will_not_remove1(
999 new NiceMock<MockService>(control_interface(),
1000 dispatcher(),
1001 metrics(),
1002 manager()));
1003
1004 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1005 .Times(5); // Once for each registration, and one after profile pop.
1006
1007 manager()->RegisterService(s_will_remove0);
1008 manager()->RegisterService(s_will_not_remove0);
1009 manager()->RegisterService(s_will_remove1);
1010 manager()->RegisterService(s_will_not_remove1);
1011
1012 // One for each service added above.
1013 ASSERT_EQ(4, manager()->services_.size());
1014
1015 scoped_refptr<MockProfile> profile0(
1016 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1017 scoped_refptr<MockProfile> profile1(
1018 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1019
1020 s_will_remove0->set_profile(profile1);
1021 s_will_remove1->set_profile(profile1);
1022 s_will_not_remove0->set_profile(profile1);
1023 s_will_not_remove1->set_profile(profile1);
1024
1025 AdoptProfile(manager(), profile0);
1026 AdoptProfile(manager(), profile1);
1027
1028 // Deny any of the services entry to profile0, so they will all be unloaded.
1029 EXPECT_CALL(*profile0, ConfigureService(_))
1030 .WillRepeatedly(Return(false));
1031
1032 EXPECT_CALL(*s_will_remove0, Unload())
1033 .WillOnce(Return(true));
1034 EXPECT_CALL(*s_will_remove1, Unload())
1035 .WillOnce(Return(true));
1036 EXPECT_CALL(*s_will_not_remove0, Unload())
1037 .WillOnce(Return(false));
1038 EXPECT_CALL(*s_will_not_remove1, Unload())
1039 .WillOnce(Return(false));
1040
1041 // This will pop profile1, which should cause all our profiles to unload.
1042 manager()->PopProfileInternal();
1043
1044 // 2 of the 4 services added above should have been unregistered and
1045 // removed, leaving 2.
1046 EXPECT_EQ(2, manager()->services_.size());
1047 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1048 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1049}
1050
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001051TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001052 {
1053 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001054 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1055 flimflam::kOfflineModeProperty,
1056 PropertyStoreTest::kBoolV,
1057 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001058 }
1059 {
1060 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001061 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1062 flimflam::kCountryProperty,
1063 PropertyStoreTest::kStringV,
1064 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001065 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001066 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001067 {
1068 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001069 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1070 flimflam::kCountryProperty,
1071 PropertyStoreTest::kBoolV,
1072 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001073 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001074 }
1075 {
1076 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001077 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1078 flimflam::kOfflineModeProperty,
1079 PropertyStoreTest::kStringV,
1080 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001081 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001082 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001083 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001084 {
1085 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001086 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001087 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001088 flimflam::kEnabledTechnologiesProperty,
1089 PropertyStoreTest::kStringsV,
1090 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001091 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001092 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001093}
1094
mukesh agrawal32399322011-09-01 10:53:43 -07001095TEST_F(ManagerTest, RequestScan) {
1096 {
1097 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001098 manager()->RegisterDevice(mock_devices_[0].get());
1099 manager()->RegisterDevice(mock_devices_[1].get());
1100 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001101 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001102 EXPECT_CALL(*mock_devices_[0], Scan(_));
1103 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001104 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001105 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001106 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001107 }
1108
1109 {
1110 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001111 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001112 EXPECT_EQ(Error::kInvalidArguments, error.type());
1113 }
1114}
1115
Darin Petkovb65c2452012-02-23 15:17:06 +01001116TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001117 KeyValueStore args;
1118 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001119 manager()->GetService(args, &e);
1120 EXPECT_EQ(Error::kInvalidArguments, e.type());
1121 EXPECT_EQ("must specify service type", e.message());
1122}
1123
1124TEST_F(ManagerTest, GetServiceUnknownType) {
1125 KeyValueStore args;
1126 Error e;
1127 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1128 manager()->GetService(args, &e);
1129 EXPECT_EQ(Error::kNotSupported, e.type());
1130 EXPECT_EQ("service type is unsupported", e.message());
1131}
1132
1133TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1134 KeyValueStore args;
1135 Error e;
1136 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1137 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001138 EXPECT_EQ(Error::kInvalidArguments, e.type());
1139 EXPECT_EQ("no wifi devices available", e.message());
1140}
1141
Darin Petkovb65c2452012-02-23 15:17:06 +01001142TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001143 KeyValueStore args;
1144 Error e;
1145 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001146 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001147 manager()->RegisterDevice(mock_wifi_);
1148 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1149 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001150 manager()->GetService(args, &e);
1151 EXPECT_TRUE(e.IsSuccess());
1152}
1153
Darin Petkov33af05c2012-02-28 10:10:30 +01001154TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1155 KeyValueStore args;
1156 Error e;
1157 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
1158 ServiceRefPtr service = manager()->GetService(args, &e);
1159 EXPECT_EQ(Error::kNotSupported, e.type());
1160 EXPECT_FALSE(service);
1161}
1162
Darin Petkovb65c2452012-02-23 15:17:06 +01001163TEST_F(ManagerTest, GetServiceVPN) {
1164 KeyValueStore args;
1165 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001166 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001167 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001168 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1169 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +01001170 ServiceRefPtr service = manager()->GetService(args, &e);
1171 EXPECT_TRUE(e.IsSuccess());
1172 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001173}
1174
Paul Stewart7f61e522012-03-22 11:13:45 -07001175TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1176 // Manager calls ActiveProfile() so we need at least one profile installed.
1177 scoped_refptr<MockProfile> profile(
1178 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1179 AdoptProfile(manager(), profile);
1180
1181 KeyValueStore args;
1182 args.SetString(flimflam::kProfileProperty, "xxx");
1183 Error error;
1184 manager()->ConfigureService(args, &error);
1185 EXPECT_EQ(Error::kInvalidArguments, error.type());
1186 EXPECT_EQ("Invalid profile name xxx", error.message());
1187}
1188
1189TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1190 // Manager calls ActiveProfile() so we need at least one profile installed.
1191 scoped_refptr<MockProfile> profile(
1192 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1193 AdoptProfile(manager(), profile);
1194
1195 KeyValueStore args;
1196 Error error;
1197 manager()->ConfigureService(args, &error);
1198 EXPECT_EQ(Error::kInvalidArguments, error.type());
1199 EXPECT_EQ("must specify service type", error.message());
1200}
1201
1202// A registered service in the ephemeral profile should be moved to the
1203// active profile as a part of configuration if no profile was explicitly
1204// specified.
1205TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1206 scoped_refptr<MockProfile> profile(
1207 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1208
1209 AdoptProfile(manager(), profile); // This is now the active profile.
1210
1211 const std::vector<uint8_t> ssid;
1212 scoped_refptr<MockWiFiService> service(
1213 new NiceMock<MockWiFiService>(control_interface(),
1214 dispatcher(),
1215 metrics(),
1216 manager(),
1217 mock_wifi_,
1218 ssid,
1219 "",
1220 "",
1221 false));
1222
1223 manager()->RegisterService(service);
1224 service->set_profile(GetEphemeralProfile(manager()));
1225
1226 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1227 // the same device as that used above causes a refcounting loop.
1228 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1229 dispatcher(),
1230 metrics(),
1231 manager(),
1232 "wifi1",
1233 "addr5",
1234 5));
1235 manager()->RegisterDevice(wifi);
1236 EXPECT_CALL(*wifi, GetService(_, _))
1237 .WillOnce(Return(service));
1238 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1239 .WillOnce(Return(true));
1240 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1241 .WillOnce(Return(true));
1242
1243 KeyValueStore args;
1244 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1245 Error error;
1246 manager()->ConfigureService(args, &error);
1247 EXPECT_TRUE(error.IsSuccess());
1248}
1249
1250// If were configure a service that was already registered and explicitly
1251// specify a profile, it should be moved from the profile it was previously
1252// in to the specified profile if one was requested.
1253TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1254 scoped_refptr<MockProfile> profile0(
1255 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1256 scoped_refptr<MockProfile> profile1(
1257 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1258
1259 const string kProfileName0 = "profile0";
1260 const string kProfileName1 = "profile1";
1261
1262 EXPECT_CALL(*profile0, GetRpcIdentifier())
1263 .WillRepeatedly(Return(kProfileName0));
1264 EXPECT_CALL(*profile1, GetRpcIdentifier())
1265 .WillRepeatedly(Return(kProfileName1));
1266
1267 AdoptProfile(manager(), profile0);
1268 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1269
1270 const std::vector<uint8_t> ssid;
1271 scoped_refptr<MockWiFiService> service(
1272 new NiceMock<MockWiFiService>(control_interface(),
1273 dispatcher(),
1274 metrics(),
1275 manager(),
1276 mock_wifi_,
1277 ssid,
1278 "",
1279 "",
1280 false));
1281
1282 manager()->RegisterService(service);
1283 service->set_profile(profile1);
1284
1285 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1286 // the same device as that used above causes a refcounting loop.
1287 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1288 dispatcher(),
1289 metrics(),
1290 manager(),
1291 "wifi1",
1292 "addr5",
1293 5));
1294 manager()->RegisterDevice(wifi);
1295 EXPECT_CALL(*wifi, GetService(_, _))
1296 .WillOnce(Return(service));
1297 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1298 .WillOnce(Return(true));
1299 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1300 .WillOnce(Return(true));
1301 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1302 .WillOnce(Return(true));
1303
1304 KeyValueStore args;
1305 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1306 args.SetString(flimflam::kProfileProperty, kProfileName0);
1307 Error error;
1308 manager()->ConfigureService(args, &error);
1309 EXPECT_TRUE(error.IsSuccess());
1310 service->set_profile(NULL); // Breaks refcounting loop.
1311}
1312
1313// An unregistered service should remain unregistered, but its contents should
1314// be saved to the specified profile nonetheless.
1315TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1316 scoped_refptr<MockProfile> profile0(
1317 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1318 scoped_refptr<MockProfile> profile1(
1319 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1320
1321 const string kProfileName0 = "profile0";
1322 const string kProfileName1 = "profile1";
1323
1324 EXPECT_CALL(*profile0, GetRpcIdentifier())
1325 .WillRepeatedly(Return(kProfileName0));
1326 EXPECT_CALL(*profile1, GetRpcIdentifier())
1327 .WillRepeatedly(Return(kProfileName1));
1328
1329 AdoptProfile(manager(), profile0);
1330 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1331
1332 const std::vector<uint8_t> ssid;
1333 scoped_refptr<MockWiFiService> service(
1334 new NiceMock<MockWiFiService>(control_interface(),
1335 dispatcher(),
1336 metrics(),
1337 manager(),
1338 mock_wifi_,
1339 ssid,
1340 "",
1341 "",
1342 false));
1343
1344 service->set_profile(profile1);
1345
1346 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1347 // the same device as that used above causes a refcounting loop.
1348 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1349 dispatcher(),
1350 metrics(),
1351 manager(),
1352 "wifi1",
1353 "addr5",
1354 5));
1355 manager()->RegisterDevice(wifi);
1356 EXPECT_CALL(*wifi, GetService(_, _))
1357 .WillOnce(Return(service));
1358 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1359 .WillOnce(Return(true));
1360 EXPECT_CALL(*profile0, AdoptService(_))
1361 .Times(0);
1362 EXPECT_CALL(*profile1, AdoptService(_))
1363 .Times(0);
1364
1365 KeyValueStore args;
1366 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1367 args.SetString(flimflam::kProfileProperty, kProfileName0);
1368 Error error;
1369 manager()->ConfigureService(args, &error);
1370 EXPECT_TRUE(error.IsSuccess());
1371}
1372
Paul Stewart22aa71b2011-09-16 12:15:11 -07001373TEST_F(ManagerTest, TechnologyOrder) {
1374 Error error;
1375 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1376 string(flimflam::kTypeWifi), &error);
1377 ASSERT_TRUE(error.IsSuccess());
1378 EXPECT_EQ(manager()->GetTechnologyOrder(),
1379 string(flimflam::kTypeEthernet) + "," +
1380 string(flimflam::kTypeWifi));
1381
1382 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1383 string(flimflam::kTypeWifi), &error);
1384 ASSERT_FALSE(error.IsSuccess());
1385 EXPECT_EQ(Error::kInvalidArguments, error.type());
1386 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1387 string(flimflam::kTypeWifi),
1388 manager()->GetTechnologyOrder());
1389}
1390
1391TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001392 // TODO(quiche): Some of these tests would probably fit better in
1393 // service_unittest, since the actual comparison of Services is
1394 // implemented in Service. (crosbug.com/23370)
1395
Paul Stewart22aa71b2011-09-16 12:15:11 -07001396 scoped_refptr<MockService> mock_service0(
1397 new NiceMock<MockService>(control_interface(),
1398 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001399 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001400 manager()));
1401 scoped_refptr<MockService> mock_service1(
1402 new NiceMock<MockService>(control_interface(),
1403 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001404 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001405 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001406
1407 manager()->RegisterService(mock_service0);
1408 manager()->RegisterService(mock_service1);
1409
1410 // Services should already be sorted by UniqueName
1411 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1412
1413 // Asking explictly to sort services should not change anything
1414 manager()->SortServices();
1415 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1416
1417 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001418 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001419 manager()->UpdateService(mock_service1);
1420 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1421
1422 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001423 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001424 manager()->UpdateService(mock_service0);
1425 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1426
1427 // Technology
1428 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1429 .WillRepeatedly(Return(true));
1430 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1431 .WillRepeatedly(Return(true));
1432 // NB: Redefine default (false) return values so we don't use the default rule
1433 // which makes the logs noisier
1434 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1435 .WillRepeatedly(Return(false));
1436 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1437 .WillRepeatedly(Return(false));
1438
1439 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001440 // Default technology ordering should favor Ethernet over WiFi.
1441 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001442 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1443
1444 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1445 string(flimflam::kTypeEthernet), &error);
1446 EXPECT_TRUE(error.IsSuccess());
1447 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1448
Gaurav Shah435de2c2011-11-17 19:01:07 -08001449 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001450 mock_service0->set_priority(1);
1451 manager()->UpdateService(mock_service0);
1452 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1453
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001454 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001455 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001456 manager()->UpdateService(mock_service1);
1457 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1458
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001459 // Auto-connect.
1460 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001461 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001462 mock_service1->set_auto_connect(false);
1463 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001464 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1465
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001466 // Connectable.
1467 mock_service1->set_connectable(true);
1468 manager()->UpdateService(mock_service1);
1469 mock_service0->set_connectable(false);
1470 manager()->UpdateService(mock_service0);
1471 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1472
1473 // IsFailed.
1474 EXPECT_CALL(*mock_service0.get(), state())
1475 .WillRepeatedly(Return(Service::kStateIdle));
1476 EXPECT_CALL(*mock_service0.get(), IsFailed())
1477 .WillRepeatedly(Return(false));
1478 manager()->UpdateService(mock_service0);
1479 EXPECT_CALL(*mock_service0.get(), state())
1480 .WillRepeatedly(Return(Service::kStateFailure));
1481 EXPECT_CALL(*mock_service1.get(), IsFailed())
1482 .WillRepeatedly(Return(true));
1483 manager()->UpdateService(mock_service1);
1484 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1485
1486 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001487 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001488 .WillRepeatedly(Return(Service::kStateAssociating));
1489 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001490 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001491 manager()->UpdateService(mock_service1);
1492 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1493
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001494 // Connected.
1495 EXPECT_CALL(*mock_service0.get(), state())
1496 .WillRepeatedly(Return(Service::kStateConnected));
1497 EXPECT_CALL(*mock_service0.get(), IsConnected())
1498 .WillRepeatedly(Return(true));
1499 manager()->UpdateService(mock_service0);
1500 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1501
Paul Stewart22aa71b2011-09-16 12:15:11 -07001502 manager()->DeregisterService(mock_service0);
1503 manager()->DeregisterService(mock_service1);
1504}
1505
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001506TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001507 MockMetrics mock_metrics;
1508 manager()->set_metrics(&mock_metrics);
1509
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001510 scoped_refptr<MockService> mock_service0(
1511 new NiceMock<MockService>(control_interface(),
1512 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001513 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001514 manager()));
1515 scoped_refptr<MockService> mock_service1(
1516 new NiceMock<MockService>(control_interface(),
1517 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001518 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001519 manager()));
1520
1521 scoped_refptr<MockConnection> mock_connection0(
1522 new NiceMock<MockConnection>(device_info_.get()));
1523 scoped_refptr<MockConnection> mock_connection1(
1524 new NiceMock<MockConnection>(device_info_.get()));
1525
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001526 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001527 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001528 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001529 manager()->RegisterService(mock_service1);
1530
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001531 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1532 manager()->SortServices();
1533
1534 mock_service1->set_priority(1);
1535 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1536 manager()->SortServices();
1537
1538 mock_service1->set_priority(0);
1539 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1540 manager()->SortServices();
1541
Paul Stewartce4ec192012-03-14 12:53:46 -07001542 mock_service0->set_mock_connection(mock_connection0);
1543 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001544
1545 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001546 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001547 manager()->SortServices();
1548
1549 mock_service1->set_priority(1);
1550 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1551 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001552 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001553 manager()->SortServices();
1554
1555 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001556 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001557 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001558 manager()->DeregisterService(mock_service1);
1559
Paul Stewartce4ec192012-03-14 12:53:46 -07001560 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001561 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001562 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001563
1564 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1565 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001566}
1567
Gaurav Shah435de2c2011-11-17 19:01:07 -08001568TEST_F(ManagerTest, AvailableTechnologies) {
1569 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1570 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001571 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001572 manager(),
1573 "null4",
1574 "addr4",
1575 0));
1576 manager()->RegisterDevice(mock_devices_[0]);
1577 manager()->RegisterDevice(mock_devices_[1]);
1578 manager()->RegisterDevice(mock_devices_[2]);
1579 manager()->RegisterDevice(mock_devices_[3]);
1580
1581 ON_CALL(*mock_devices_[0].get(), technology())
1582 .WillByDefault(Return(Technology::kEthernet));
1583 ON_CALL(*mock_devices_[1].get(), technology())
1584 .WillByDefault(Return(Technology::kWifi));
1585 ON_CALL(*mock_devices_[2].get(), technology())
1586 .WillByDefault(Return(Technology::kCellular));
1587 ON_CALL(*mock_devices_[3].get(), technology())
1588 .WillByDefault(Return(Technology::kWifi));
1589
1590 set<string> expected_technologies;
1591 expected_technologies.insert(Technology::NameFromIdentifier(
1592 Technology::kEthernet));
1593 expected_technologies.insert(Technology::NameFromIdentifier(
1594 Technology::kWifi));
1595 expected_technologies.insert(Technology::NameFromIdentifier(
1596 Technology::kCellular));
1597 Error error;
1598 vector<string> technologies = manager()->AvailableTechnologies(&error);
1599
1600 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1601 ContainerEq(expected_technologies));
1602}
1603
1604TEST_F(ManagerTest, ConnectedTechnologies) {
1605 scoped_refptr<MockService> connected_service1(
1606 new NiceMock<MockService>(control_interface(),
1607 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001608 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001609 manager()));
1610 scoped_refptr<MockService> connected_service2(
1611 new NiceMock<MockService>(control_interface(),
1612 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001613 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001614 manager()));
1615 scoped_refptr<MockService> disconnected_service1(
1616 new NiceMock<MockService>(control_interface(),
1617 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001618 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001619 manager()));
1620 scoped_refptr<MockService> disconnected_service2(
1621 new NiceMock<MockService>(control_interface(),
1622 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001623 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001624 manager()));
1625
1626 ON_CALL(*connected_service1.get(), IsConnected())
1627 .WillByDefault(Return(true));
1628 ON_CALL(*connected_service2.get(), IsConnected())
1629 .WillByDefault(Return(true));
1630
1631 manager()->RegisterService(connected_service1);
1632 manager()->RegisterService(connected_service2);
1633 manager()->RegisterService(disconnected_service1);
1634 manager()->RegisterService(disconnected_service2);
1635
1636 manager()->RegisterDevice(mock_devices_[0]);
1637 manager()->RegisterDevice(mock_devices_[1]);
1638 manager()->RegisterDevice(mock_devices_[2]);
1639 manager()->RegisterDevice(mock_devices_[3]);
1640
1641 ON_CALL(*mock_devices_[0].get(), technology())
1642 .WillByDefault(Return(Technology::kEthernet));
1643 ON_CALL(*mock_devices_[1].get(), technology())
1644 .WillByDefault(Return(Technology::kWifi));
1645 ON_CALL(*mock_devices_[2].get(), technology())
1646 .WillByDefault(Return(Technology::kCellular));
1647 ON_CALL(*mock_devices_[3].get(), technology())
1648 .WillByDefault(Return(Technology::kWifi));
1649
1650 mock_devices_[0]->SelectService(connected_service1);
1651 mock_devices_[1]->SelectService(disconnected_service1);
1652 mock_devices_[2]->SelectService(disconnected_service2);
1653 mock_devices_[3]->SelectService(connected_service2);
1654
1655 set<string> expected_technologies;
1656 expected_technologies.insert(Technology::NameFromIdentifier(
1657 Technology::kEthernet));
1658 expected_technologies.insert(Technology::NameFromIdentifier(
1659 Technology::kWifi));
1660 Error error;
1661
1662 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1663 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1664 ContainerEq(expected_technologies));
1665}
1666
1667TEST_F(ManagerTest, DefaultTechnology) {
1668 scoped_refptr<MockService> connected_service(
1669 new NiceMock<MockService>(control_interface(),
1670 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001671 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001672 manager()));
1673 scoped_refptr<MockService> disconnected_service(
1674 new NiceMock<MockService>(control_interface(),
1675 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001676 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001677 manager()));
1678
1679 // Connected. WiFi.
1680 ON_CALL(*connected_service.get(), IsConnected())
1681 .WillByDefault(Return(true));
1682 ON_CALL(*connected_service.get(), state())
1683 .WillByDefault(Return(Service::kStateConnected));
1684 ON_CALL(*connected_service.get(), technology())
1685 .WillByDefault(Return(Technology::kWifi));
1686
1687 // Disconnected. Ethernet.
1688 ON_CALL(*disconnected_service.get(), technology())
1689 .WillByDefault(Return(Technology::kEthernet));
1690
1691 manager()->RegisterService(disconnected_service);
1692 Error error;
1693 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1694
1695
1696 manager()->RegisterService(connected_service);
1697 // Connected service should be brought to the front now.
1698 string expected_technology =
1699 Technology::NameFromIdentifier(Technology::kWifi);
1700 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1701}
1702
Thieu Le1271d682011-11-02 22:48:19 +00001703TEST_F(ManagerTest, DisconnectServicesOnStop) {
1704 scoped_refptr<MockService> mock_service(
1705 new NiceMock<MockService>(control_interface(),
1706 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001707 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001708 manager()));
1709 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001710 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001711 manager()->Stop();
1712}
1713
mukesh agrawal00917ce2011-11-22 23:56:55 +00001714TEST_F(ManagerTest, UpdateServiceConnected) {
1715 scoped_refptr<MockService> mock_service(
1716 new NiceMock<MockService>(control_interface(),
1717 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001718 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001719 manager()));
1720 manager()->RegisterService(mock_service);
1721 EXPECT_FALSE(mock_service->favorite());
1722 EXPECT_FALSE(mock_service->auto_connect());
1723
Gaurav Shah435de2c2011-11-17 19:01:07 -08001724 EXPECT_CALL(*mock_service.get(), IsConnected())
1725 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001726 manager()->UpdateService(mock_service);
1727 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1728 // to mock out MakeFavorite. And mocking that out would break the
1729 // SortServices test. (crosbug.com/23370)
1730 EXPECT_TRUE(mock_service->favorite());
1731 EXPECT_TRUE(mock_service->auto_connect());
1732}
1733
Thieu Led4e9e552012-02-16 16:26:07 -08001734TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1735 // This tests the case where the user connects to a service that is
1736 // currently associated with a profile. We want to make sure that the
1737 // favorite flag is set and that the flag is saved to the current
1738 // profile.
1739 scoped_refptr<MockService> mock_service(
1740 new NiceMock<MockService>(control_interface(),
1741 dispatcher(),
1742 metrics(),
1743 manager()));
1744 manager()->RegisterService(mock_service);
1745 EXPECT_FALSE(mock_service->favorite());
1746 EXPECT_FALSE(mock_service->auto_connect());
1747
Gary Moraind93615e2012-04-27 11:50:03 -07001748 scoped_refptr<MockProfile> profile(
1749 new MockProfile(control_interface(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08001750
Gary Moraind93615e2012-04-27 11:50:03 -07001751 mock_service->set_profile(profile);
1752 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08001753 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07001754 EXPECT_CALL(*profile,
1755 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08001756 manager()->UpdateService(mock_service);
1757 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1758 // to mock out MakeFavorite. And mocking that out would break the
1759 // SortServices test. (crosbug.com/23370)
1760 EXPECT_TRUE(mock_service->favorite());
1761 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07001762 // This releases the ref on the mock profile.
1763 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08001764}
1765
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001766TEST_F(ManagerTest, SaveSuccessfulService) {
1767 scoped_refptr<MockProfile> profile(
1768 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1769 AdoptProfile(manager(), profile);
1770 scoped_refptr<MockService> service(
1771 new NiceMock<MockService>(control_interface(),
1772 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001773 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001774 manager()));
1775
1776 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1777 ServiceRefPtr expect_service(service.get());
1778
1779 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1780 .WillOnce(Return(false));
1781 manager()->RegisterService(service);
1782
1783 EXPECT_CALL(*service.get(), state())
1784 .WillRepeatedly(Return(Service::kStateConnected));
1785 EXPECT_CALL(*service.get(), IsConnected())
1786 .WillRepeatedly(Return(true));
1787 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1788 .WillOnce(Return(true));
1789 manager()->UpdateService(service);
1790}
1791
Paul Stewart1b253142012-01-26 14:05:52 -08001792TEST_F(ManagerTest, EnumerateProfiles) {
1793 vector<string> profile_paths;
1794 for (size_t i = 0; i < 10; i++) {
1795 scoped_refptr<MockProfile> profile(
1796 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001797 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001798 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1799 .WillOnce(Return(profile_paths.back()));
1800 AdoptProfile(manager(), profile);
1801 }
1802
1803 Error error;
1804 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1805 EXPECT_TRUE(error.IsSuccess());
1806 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1807 for (size_t i = 0; i < profile_paths.size(); i++) {
1808 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1809 }
1810}
1811
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001812TEST_F(ManagerTest, AutoConnectOnRegister) {
1813 MockServiceRefPtr service = MakeAutoConnectableService();
1814 EXPECT_CALL(*service.get(), AutoConnect());
1815 manager()->RegisterService(service);
1816 dispatcher()->DispatchPendingEvents();
1817}
1818
1819TEST_F(ManagerTest, AutoConnectOnUpdate) {
1820 MockServiceRefPtr service1 = MakeAutoConnectableService();
1821 service1->set_priority(1);
1822 MockServiceRefPtr service2 = MakeAutoConnectableService();
1823 service2->set_priority(2);
1824 manager()->RegisterService(service1);
1825 manager()->RegisterService(service2);
1826 dispatcher()->DispatchPendingEvents();
1827
1828 EXPECT_CALL(*service1.get(), AutoConnect());
1829 EXPECT_CALL(*service2.get(), state())
1830 .WillRepeatedly(Return(Service::kStateFailure));
1831 EXPECT_CALL(*service2.get(), IsFailed())
1832 .WillRepeatedly(Return(true));
1833 EXPECT_CALL(*service2.get(), IsConnected())
1834 .WillRepeatedly(Return(false));
1835 manager()->UpdateService(service2);
1836 dispatcher()->DispatchPendingEvents();
1837}
1838
1839TEST_F(ManagerTest, AutoConnectOnDeregister) {
1840 MockServiceRefPtr service1 = MakeAutoConnectableService();
1841 service1->set_priority(1);
1842 MockServiceRefPtr service2 = MakeAutoConnectableService();
1843 service2->set_priority(2);
1844 manager()->RegisterService(service1);
1845 manager()->RegisterService(service2);
1846 dispatcher()->DispatchPendingEvents();
1847
1848 EXPECT_CALL(*service1.get(), AutoConnect());
1849 manager()->DeregisterService(service2);
1850 dispatcher()->DispatchPendingEvents();
1851}
1852
Paul Stewartc681fa02012-03-02 19:40:04 -08001853TEST_F(ManagerTest, RecheckPortal) {
1854 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1855 .WillOnce(Return(false));
1856 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1857 .WillOnce(Return(true));
1858 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1859 .Times(0);
1860
1861 manager()->RegisterDevice(mock_devices_[0]);
1862 manager()->RegisterDevice(mock_devices_[1]);
1863 manager()->RegisterDevice(mock_devices_[2]);
1864
1865 manager()->RecheckPortal(NULL);
1866}
1867
Paul Stewartd215af62012-04-24 23:25:50 -07001868TEST_F(ManagerTest, RecheckPortalOnService) {
1869 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1870 dispatcher(),
1871 metrics(),
1872 manager());
1873 EXPECT_CALL(*mock_devices_[0].get(),
1874 IsConnectedToService(IsRefPtrTo(service)))
1875 .WillOnce(Return(false));
1876 EXPECT_CALL(*mock_devices_[1].get(),
1877 IsConnectedToService(IsRefPtrTo(service)))
1878 .WillOnce(Return(true));
1879 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
1880 .WillOnce(Return(true));
1881 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
1882 .Times(0);
1883
1884 manager()->RegisterDevice(mock_devices_[0]);
1885 manager()->RegisterDevice(mock_devices_[1]);
1886 manager()->RegisterDevice(mock_devices_[2]);
1887
1888 manager()->RecheckPortalOnService(service);
1889}
1890
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001891TEST_F(ManagerTest, GetDefaultService) {
1892 EXPECT_FALSE(manager()->GetDefaultService().get());
1893
1894 scoped_refptr<MockService> mock_service(
1895 new NiceMock<MockService>(control_interface(),
1896 dispatcher(),
1897 metrics(),
1898 manager()));
1899
1900 manager()->RegisterService(mock_service);
1901 EXPECT_FALSE(manager()->GetDefaultService().get());
1902
1903 scoped_refptr<MockConnection> mock_connection(
1904 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001905 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001906 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1907
Paul Stewartce4ec192012-03-14 12:53:46 -07001908 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001909 manager()->DeregisterService(mock_service);
1910}
1911
Paul Stewart13ed2252012-03-21 12:52:46 -07001912TEST_F(ManagerTest, GetServiceWithGUID) {
1913 scoped_refptr<MockService> mock_service0(
1914 new NiceMock<MockService>(control_interface(),
1915 dispatcher(),
1916 metrics(),
1917 manager()));
1918
1919 scoped_refptr<MockService> mock_service1(
1920 new NiceMock<MockService>(control_interface(),
1921 dispatcher(),
1922 metrics(),
1923 manager()));
1924
Paul Stewartcb59fed2012-03-21 21:14:46 -07001925 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1926 .Times(0);
1927 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1928 .Times(0);
1929
Paul Stewart13ed2252012-03-21 12:52:46 -07001930 manager()->RegisterService(mock_service0);
1931 manager()->RegisterService(mock_service1);
1932
1933 const string kGUID0 = "GUID0";
1934 const string kGUID1 = "GUID1";
1935
1936 {
1937 Error error;
1938 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1939 EXPECT_FALSE(error.IsSuccess());
1940 EXPECT_FALSE(service);
1941 }
1942
1943 KeyValueStore args;
1944 args.SetString(flimflam::kGuidProperty, kGUID1);
1945
1946 {
1947 Error error;
1948 ServiceRefPtr service = manager()->GetService(args, &error);
1949 EXPECT_EQ(Error::kInvalidArguments, error.type());
1950 EXPECT_FALSE(service);
1951 }
1952
1953 mock_service0->set_guid(kGUID0);
1954 mock_service1->set_guid(kGUID1);
1955
1956 {
1957 Error error;
1958 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1959 EXPECT_TRUE(error.IsSuccess());
1960 EXPECT_EQ(mock_service0.get(), service.get());
1961 }
1962
1963 {
1964 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07001965 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
1966 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07001967 ServiceRefPtr service = manager()->GetService(args, &error);
1968 EXPECT_TRUE(error.IsSuccess());
1969 EXPECT_EQ(mock_service1.get(), service.get());
1970 }
1971
1972 manager()->DeregisterService(mock_service0);
1973 manager()->DeregisterService(mock_service1);
1974}
1975
Gary Morain028545d2012-04-07 14:55:52 -07001976
1977TEST_F(ManagerTest, CalculateStateOffline) {
1978 MockMetrics mock_metrics;
1979 manager()->set_metrics(&mock_metrics);
1980 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
1981 .Times(AnyNumber());
1982 scoped_refptr<MockService> mock_service0(
1983 new NiceMock<MockService>(control_interface(),
1984 dispatcher(),
1985 metrics(),
1986 manager()));
1987
1988 scoped_refptr<MockService> mock_service1(
1989 new NiceMock<MockService>(control_interface(),
1990 dispatcher(),
1991 metrics(),
1992 manager()));
1993
1994 EXPECT_CALL(*mock_service0.get(), IsConnected())
1995 .WillRepeatedly(Return(false));
1996 EXPECT_CALL(*mock_service1.get(), IsConnected())
1997 .WillRepeatedly(Return(false));
1998
1999 manager()->RegisterService(mock_service0);
2000 manager()->RegisterService(mock_service1);
2001
2002 EXPECT_EQ("offline", manager()->CalculateState(NULL));
2003
2004 manager()->DeregisterService(mock_service0);
2005 manager()->DeregisterService(mock_service1);
2006}
2007
2008TEST_F(ManagerTest, CalculateStateOnline) {
2009 MockMetrics mock_metrics;
2010 manager()->set_metrics(&mock_metrics);
2011 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2012 .Times(AnyNumber());
2013 scoped_refptr<MockService> mock_service0(
2014 new NiceMock<MockService>(control_interface(),
2015 dispatcher(),
2016 metrics(),
2017 manager()));
2018
2019 scoped_refptr<MockService> mock_service1(
2020 new NiceMock<MockService>(control_interface(),
2021 dispatcher(),
2022 metrics(),
2023 manager()));
2024
2025 EXPECT_CALL(*mock_service0.get(), IsConnected())
2026 .WillRepeatedly(Return(false));
2027 EXPECT_CALL(*mock_service1.get(), IsConnected())
2028 .WillRepeatedly(Return(true));
2029 EXPECT_CALL(*mock_service0.get(), state())
2030 .WillRepeatedly(Return(Service::kStateIdle));
2031 EXPECT_CALL(*mock_service1.get(), state())
2032 .WillRepeatedly(Return(Service::kStateConnected));
2033
2034 manager()->RegisterService(mock_service0);
2035 manager()->RegisterService(mock_service1);
2036
2037 EXPECT_EQ("online", manager()->CalculateState(NULL));
2038
2039 manager()->DeregisterService(mock_service0);
2040 manager()->DeregisterService(mock_service1);
2041}
2042
Paul Stewart10e9e4e2012-04-26 19:46:28 -07002043TEST_F(ManagerTest, StartupPortalList) {
2044 // Simulate loading value from the default profile.
2045 const string kProfileValue("wifi,vpn");
2046 manager()->props_.check_portal_list = kProfileValue;
2047
2048 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
2049 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2050 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2051
2052 const string kStartupValue("cellular,ethernet");
2053 manager()->SetStartupPortalList(kStartupValue);
2054 // Ensure profile value is not overwritten, so when we save the default
2055 // profile, the correct value will still be written.
2056 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
2057
2058 // However we should read back a different list.
2059 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
2060 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2061 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2062
2063 const string kRuntimeValue("ppp");
2064 // Setting a runtime value over the control API should overwrite both
2065 // the profile value and what we read back.
2066 Error error;
2067 manager()->mutable_store()->SetStringProperty(
2068 flimflam::kCheckPortalListProperty,
2069 kRuntimeValue,
2070 &error);
2071 ASSERT_TRUE(error.IsSuccess());
2072 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
2073 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
2074 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2075 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
2076}
2077
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002078TEST_F(ManagerTest, EnableTechnology) {
2079 Error error(Error::kOperationInitiated);
2080 ResultCallback callback;
2081 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2082 EXPECT_TRUE(error.IsSuccess());
2083
2084 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2085 .WillByDefault(Return(true));
2086
2087 manager()->RegisterDevice(mock_devices_[0]);
2088
2089 // Device is enabled, so expect operation is successful.
2090 mock_devices_[0]->enabled_ = true;
2091 error.Populate(Error::kOperationInitiated);
2092 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2093 EXPECT_TRUE(error.IsSuccess());
2094
2095 // Device is disabled, so expect operation in progress.
2096 mock_devices_[0]->enabled_ = false;
2097 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
2098 error.Populate(Error::kOperationInitiated);
2099 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2100 EXPECT_TRUE(error.IsOngoing());
2101}
2102
2103TEST_F(ManagerTest, DisableTechnology) {
2104 Error error(Error::kOperationInitiated);
2105 ResultCallback callback;
2106 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2107 EXPECT_TRUE(error.IsSuccess());
2108
2109 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2110 .WillByDefault(Return(true));
2111
2112 manager()->RegisterDevice(mock_devices_[0]);
2113
2114 // Device is disabled, so expect operation is successful.
2115 error.Populate(Error::kOperationInitiated);
2116 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2117 EXPECT_TRUE(error.IsSuccess());
2118
2119 // Device is enabled, so expect operation in progress.
2120 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
2121 mock_devices_[0]->enabled_ = true;
2122 error.Populate(Error::kOperationInitiated);
2123 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2124 EXPECT_TRUE(error.IsOngoing());
2125}
2126
2127
Chris Masone9be4a9d2011-05-16 15:44:09 -07002128} // namespace shill