blob: 18f1f75d16929945022d2c1996683f0c3bc9d2b6 [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
Chris Masone6791a432011-07-12 13:23:19 -07007#include <set>
8
Chris Masone9be4a9d2011-05-16 15:44:09 -07009#include <glib.h>
10
Paul Stewarte73d05c2012-03-29 16:26:05 -070011#include <base/file_util.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070012#include <base/logging.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050013#include <base/scoped_temp_dir.h>
14#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070015#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070017#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070018#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070019
mukesh agrawal32399322011-09-01 10:53:43 -070020#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070021#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070022#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070023#include "shill/glib.h"
24#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070025#include "shill/key_value_store.h"
mukesh agrawal32399322011-09-01 10:53:43 -070026#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080027#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070028#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070029#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080030#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070031#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000032#include "shill/mock_metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070033#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070034#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070035#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070036#include "shill/mock_wifi.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070037#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070038#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070039#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070040#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070041
42using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070043using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070044using std::string;
45using std::vector;
46
Chris Masone9be4a9d2011-05-16 15:44:09 -070047namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070048using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070049using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080050using ::testing::ContainerEq;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070051using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070052using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070053using ::testing::NiceMock;
54using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070055using ::testing::ReturnRef;
Gaurav Shah435de2c2011-11-17 19:01:07 -080056using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080057using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070058using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070059
Chris Masone3bd3c8c2011-06-13 08:20:26 -070060class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070061 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070062 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070063 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070064 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080065 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070066 manager(),
67 "wifi0",
68 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080069 4)),
70 device_info_(new NiceMock<MockDeviceInfo>(
71 control_interface(),
72 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080073 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080074 reinterpret_cast<Manager*>(NULL))),
75 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070076 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
77 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080078 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070079 manager(),
80 "null0",
81 "addr0",
82 0));
83 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
84 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080085 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070086 manager(),
87 "null1",
88 "addr1",
89 1));
90 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
91 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080092 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070093 manager(),
94 "null2",
95 "addr2",
96 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080097 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
98 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080099 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800100 manager(),
101 "null3",
102 "addr3",
103 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700104 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800105
106 // Replace the manager's adaptor with a quieter one, and one
107 // we can do EXPECT*() against. Passes ownership.
108 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700109 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700110 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700111
Paul Stewartfdd16072011-09-16 12:41:35 -0700112 bool IsDeviceRegistered(const DeviceRefPtr &device,
113 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700114 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700115 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700116 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700117 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700118 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700119
Paul Stewarta849a3d2011-11-03 05:54:09 -0700120 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
121 manager->profiles_.push_back(profile);
122 }
123
Paul Stewart75225512012-01-26 22:51:33 -0800124 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
125 return manager->ephemeral_profile_;
126 }
127
Chris Masone6515aab2011-10-12 16:19:09 -0700128 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
129 Profile::Identifier id("rather", "irrelevant");
130 scoped_ptr<Profile> profile(new Profile(control_interface(),
131 manager,
132 id,
133 "",
134 false));
135 FilePath final_path(storage_path());
136 final_path = final_path.Append("test.profile");
137 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
138 storage->set_path(final_path);
139 if (!storage->Open())
140 return NULL;
141 profile->set_storage(storage.release()); // Passes ownership.
142 return profile.release();
143 }
144
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700145 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
146 const string &profile_identifier,
147 const string &service_name) {
148 GLib glib;
149 KeyFileStore store(&glib);
150 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
151 return store.Open() &&
152 store.SetString(service_name, "rather", "irrelevant") &&
153 store.Close();
154 }
155
156 Error::Type TestCreateProfile(Manager *manager, const string &name) {
157 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800158 string path;
159 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700160 return error.type();
161 }
162
163 Error::Type TestPopAnyProfile(Manager *manager) {
164 Error error;
165 manager->PopAnyProfile(&error);
166 return error.type();
167 }
168
169 Error::Type TestPopProfile(Manager *manager, const string &name) {
170 Error error;
171 manager->PopProfile(name, &error);
172 return error.type();
173 }
174
175 Error::Type TestPushProfile(Manager *manager, const string &name) {
176 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800177 string path;
178 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700179 return error.type();
180 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000181
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700182 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000183 typedef scoped_refptr<MockService> MockServiceRefPtr;
184
185 MockServiceRefPtr MakeAutoConnectableService() {
186 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
187 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800188 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000189 manager());
190 service->MakeFavorite();
191 service->set_connectable(true);
192 return service;
193 }
194
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700195 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700196 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800197 scoped_ptr<MockDeviceInfo> device_info_;
198
199 // This pointer is owned by the manager, and only tracked here for EXPECT*()
200 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700201};
202
Paul Stewart22aa71b2011-09-16 12:15:11 -0700203bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
204 return (svc0.get() == manager()->services_[0].get() &&
205 svc1.get() == manager()->services_[1].get());
206}
207
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700208TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700209 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
210 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700211}
212
Chris Masone9be4a9d2011-05-16 15:44:09 -0700213TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700214 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700215 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700216 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700217 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700218 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700219 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700220
Paul Stewart22aa71b2011-09-16 12:15:11 -0700221 manager()->RegisterDevice(mock_devices_[0]);
222 manager()->RegisterDevice(mock_devices_[1]);
223 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700224
Paul Stewart22aa71b2011-09-16 12:15:11 -0700225 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
226 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
227 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700228}
229
Paul Stewarta41e38d2011-11-11 07:47:29 -0800230TEST_F(ManagerTest, DeviceRegistrationAndStart) {
231 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500232 mock_devices_[0]->enabled_persistent_ = true;
233 mock_devices_[1]->enabled_persistent_ = false;
234 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800235 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500236 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800237 .Times(0);
238 manager()->RegisterDevice(mock_devices_[0]);
239 manager()->RegisterDevice(mock_devices_[1]);
240}
241
242TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
243 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
244 DeviceRefPtr device_ref(mock_devices_[0].get());
245 AdoptProfile(manager(), profile); // Passes ownership.
246 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
247 EXPECT_CALL(*profile, Save());
248 manager()->RegisterDevice(mock_devices_[0]);
249}
250
Chris Masone9be4a9d2011-05-16 15:44:09 -0700251TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700252 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700253 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700254 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700255 .WillByDefault(Return(true));
256
Gaurav Shah435de2c2011-11-17 19:01:07 -0800257 manager()->RegisterDevice(mock_devices_[0]);
258 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700259
Paul Stewart22aa71b2011-09-16 12:15:11 -0700260 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
261 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700262
Eric Shienbrood9a245532012-03-07 14:20:39 -0500263 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800264 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700265 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700266
Eric Shienbrood9a245532012-03-07 14:20:39 -0500267 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800268 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700269 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700270}
271
272TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700273 // It's much easier and safer to use a real GLib for this test.
274 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700275 Manager manager(control_interface(),
276 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800277 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700278 &glib,
279 run_path(),
280 storage_path(),
281 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700282 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
283 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700284 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700285
Chris Masone9be4a9d2011-05-16 15:44:09 -0700286 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700287 new NiceMock<MockService>(control_interface(),
288 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800289 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700290 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700291 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700292 new NiceMock<MockService>(control_interface(),
293 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800294 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700295 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700296
mukesh agrawal51a7e932011-07-27 16:18:26 -0700297 string service1_name(mock_service->UniqueName());
298 string service2_name(mock_service2->UniqueName());
299
300 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
301 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700302 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700303 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700304 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700305 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700306 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700307
Chris Masone9d779932011-08-25 16:33:41 -0700308 manager.RegisterService(mock_service);
309 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700310
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800311 Error error;
312 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700313 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700314 EXPECT_EQ(2, ids.size());
315 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
316 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700317
Chris Masone9d779932011-08-25 16:33:41 -0700318 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
319 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
320
321 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700322}
323
Chris Masone6515aab2011-10-12 16:19:09 -0700324TEST_F(ManagerTest, RegisterKnownService) {
325 // It's much easier and safer to use a real GLib for this test.
326 GLib glib;
327 Manager manager(control_interface(),
328 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800329 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700330 &glib,
331 run_path(),
332 storage_path(),
333 string());
334 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
335 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700336 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700337 {
338 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
339 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800340 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700341 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700342 ASSERT_TRUE(profile->AdoptService(service1));
343 ASSERT_TRUE(profile->ContainsService(service1));
344 } // Force destruction of service1.
345
346 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
347 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800348 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700349 &manager));
350 manager.RegisterService(service2);
351 EXPECT_EQ(service2->profile().get(), profile.get());
352 manager.Stop();
353}
354
355TEST_F(ManagerTest, RegisterUnknownService) {
356 // It's much easier and safer to use a real GLib for this test.
357 GLib glib;
358 Manager manager(control_interface(),
359 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800360 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700361 &glib,
362 run_path(),
363 storage_path(),
364 string());
365 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
366 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700367 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700368 {
369 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
370 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800371 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700372 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700373 ASSERT_TRUE(profile->AdoptService(service1));
374 ASSERT_TRUE(profile->ContainsService(service1));
375 } // Force destruction of service1.
376 scoped_refptr<MockService> mock_service2(
377 new NiceMock<MockService>(control_interface(),
378 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700380 &manager));
381 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
382 .WillRepeatedly(Return(mock_service2->UniqueName()));
383 manager.RegisterService(mock_service2);
384 EXPECT_NE(mock_service2->profile().get(), profile.get());
385 manager.Stop();
386}
387
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000388TEST_F(ManagerTest, DeregisterUnregisteredService) {
389 // WiFi assumes that it can deregister a service that is not
390 // registered. (E.g. a hidden service can be deregistered when it
391 // loses its last endpoint, and again when WiFi is Stop()-ed.)
392 //
393 // So test that doing so doesn't cause a crash.
394 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
395 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800396 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000397 manager());
398 manager()->DeregisterService(service);
399}
400
Chris Masonea8a2c252011-06-27 22:16:30 -0700401TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700402 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700403 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700404 map<string, ::DBus::Variant> props;
405 Error error(Error::kInvalidProperty, "");
406 {
407 ::DBus::Error dbus_error;
408 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700409 manager()->mutable_store()->SetStringProperty(
410 flimflam::kCheckPortalListProperty,
411 expected,
412 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700413 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700414 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
415 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
416 expected);
417 }
418 {
419 ::DBus::Error dbus_error;
420 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700421 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
422 expected,
423 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700424 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700425 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
426 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
427 expected);
428 }
429}
430
Chris Masone3c3f6a12011-07-01 10:01:41 -0700431TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700432 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700433 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800434 manager()->RegisterDevice(mock_devices_[0]);
435 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700436 {
437 map<string, ::DBus::Variant> props;
438 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700439 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700440 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
441 Strings devices =
442 props[flimflam::kDevicesProperty].operator vector<string>();
443 EXPECT_EQ(2, devices.size());
444 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700445}
446
mukesh agrawal2366eed2012-03-20 18:21:50 -0700447TEST_F(ManagerTest, GetServicesProperty) {
448 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
449 AdoptProfile(manager(), profile);
450 map<string, ::DBus::Variant> props;
451 ::DBus::Error dbus_error;
452 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
453 map<string, ::DBus::Variant>::const_iterator prop =
454 props.find(flimflam::kServicesProperty);
455 ASSERT_FALSE(prop == props.end());
456 const ::DBus::Variant &variant = prop->second;
457 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
458}
459
Chris Masone6791a432011-07-12 13:23:19 -0700460TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700461 Manager manager(control_interface(),
462 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800463 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700464 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700465 run_path(),
466 storage_path(),
467 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700468 scoped_refptr<MockService> s2(new MockService(control_interface(),
469 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800470 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700471 &manager));
472 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700473 {
Chris Masone6515aab2011-10-12 16:19:09 -0700474 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700475 ProfileRefPtr profile(
476 new Profile(control_interface(), &manager, id, "", false));
477 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700478 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700479 .WillRepeatedly(Return(true));
480 EXPECT_CALL(*storage, Flush())
481 .Times(AnyNumber())
482 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700483 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700484 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700485 }
Chris Masone6515aab2011-10-12 16:19:09 -0700486 // Create a profile that already has |s2| in it.
487 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700488 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700489
Chris Masone6515aab2011-10-12 16:19:09 -0700490 // Now, move the Service |s2| to another profile.
491 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
492 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700493
494 // Force destruction of the original Profile, to ensure that the Service
495 // is kept alive and populated with data.
496 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700497 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700498 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700499}
500
Paul Stewart7f61e522012-03-22 11:13:45 -0700501TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
502 scoped_refptr<MockProfile> mock_profile(
503 new MockProfile(control_interface(), manager(), ""));
504 const string kProfileName("profile0");
505 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
506 .WillRepeatedly(Return(kProfileName));
507 AdoptProfile(manager(), mock_profile);
508
509 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
510 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
511 EXPECT_EQ(mock_profile.get(), profile.get());
512}
513
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800514TEST_F(ManagerTest, SetProfileForService) {
515 scoped_refptr<MockProfile> profile0(
516 new MockProfile(control_interface(), manager(), ""));
517 string profile_name0("profile0");
518 EXPECT_CALL(*profile0, GetRpcIdentifier())
519 .WillRepeatedly(Return(profile_name0));
520 AdoptProfile(manager(), profile0);
521 scoped_refptr<MockService> service(new MockService(control_interface(),
522 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800523 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800524 manager()));
525 service->set_profile(profile0);
526
527 {
528 Error error;
529 manager()->SetProfileForService(service, "foo", &error);
530 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700531 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800532 }
533
534 {
535 Error error;
536 manager()->SetProfileForService(service, profile_name0, &error);
537 EXPECT_EQ(Error::kInvalidArguments, error.type());
538 EXPECT_EQ("Service is already connected to this profile", error.message());
539 }
540
541 scoped_refptr<MockProfile> profile1(
542 new MockProfile(control_interface(), manager(), ""));
543 string profile_name1("profile1");
544 EXPECT_CALL(*profile1, GetRpcIdentifier())
545 .WillRepeatedly(Return(profile_name1));
546 AdoptProfile(manager(), profile1);
547
548 {
549 Error error;
550 EXPECT_CALL(*profile1, AdoptService(_))
551 .WillOnce(Return(true));
552 EXPECT_CALL(*profile0, AbandonService(_))
553 .WillOnce(Return(true));
554 manager()->SetProfileForService(service, profile_name1, &error);
555 EXPECT_TRUE(error.IsSuccess());
556 }
557}
558
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700559TEST_F(ManagerTest, CreateProfile) {
560 // It's much easier to use real Glib here since we want the storage
561 // side-effects.
562 GLib glib;
563 ScopedTempDir temp_dir;
564 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
565
566 Manager manager(control_interface(),
567 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800568 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700569 &glib,
570 run_path(),
571 storage_path(),
572 temp_dir.path().value());
573
574 // Invalid name should be rejected.
575 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
576
Paul Stewartd0a3b812012-03-28 22:48:22 -0700577 // A profile with invalid characters in it should similarly be rejected.
578 EXPECT_EQ(Error::kInvalidArguments,
579 TestCreateProfile(&manager, "valid_profile"));
580
581 // We should be able to create a machine profile.
582 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700583
584 // We should succeed in creating a valid user profile.
585 const char kProfile[] = "~user/profile";
586 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
587
588 // We should fail in creating it a second time (already exists).
589 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
590}
591
592TEST_F(ManagerTest, PushPopProfile) {
593 // It's much easier to use real Glib in creating a Manager for this
594 // test here since we want the storage side-effects.
595 GLib glib;
596 ScopedTempDir temp_dir;
597 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
598 Manager manager(control_interface(),
599 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800600 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700601 &glib,
602 run_path(),
603 storage_path(),
604 temp_dir.path().value());
605
606 // Pushing an invalid profile should fail.
607 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
608
Paul Stewartd0a3b812012-03-28 22:48:22 -0700609 // Pushing a default profile that does not exist should fail.
610 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700611
612 const char kProfile0[] = "~user/profile0";
613 const char kProfile1[] = "~user/profile1";
614
615 // Create a couple of profiles.
616 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
617 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
618
619 // Push these profiles on the stack.
620 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
621 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
622
623 // Pushing a profile a second time should fail.
624 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
625 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
626
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800627 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700628 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800629 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700630
631 // Make sure a profile name that doesn't exist fails.
632 const char kProfile2Id[] = "profile2";
633 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
634 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
635
636 // Create a new service, with a specific storage name.
637 scoped_refptr<MockService> service(
638 new NiceMock<MockService>(control_interface(),
639 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800640 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700641 &manager));
642 const char kServiceName[] = "service_storage_name";
643 EXPECT_CALL(*service.get(), GetStorageIdentifier())
644 .WillRepeatedly(Return(kServiceName));
645 EXPECT_CALL(*service.get(), Load(_))
646 .WillRepeatedly(Return(true));
647
648 // Add this service to the manager -- it should end up in the ephemeral
649 // profile.
650 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800651 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700652
653 // Create storage for a profile that contains the service storage name.
654 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
655 kServiceName));
656
657 // When we push the profile, the service should move away from the
658 // ephemeral profile to this new profile since it has an entry for
659 // this service.
660 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800661 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700662 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
663
664 // Insert another profile that should supersede ownership of the service.
665 const char kProfile3Id[] = "profile3";
666 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
667 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
668 kServiceName));
669 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
670 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
671
672 // Popping an invalid profile name should fail.
673 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
674
675 // Popping an profile that is not at the top of the stack should fail.
676 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
677
678 // Popping the top profile should succeed.
679 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
680
681 // Moreover the service should have switched profiles to profile 2.
682 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
683
684 // Popping the top profile should succeed.
685 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
686
687 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800688 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700689
690 // Pop the remaining two services off the stack.
691 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
692 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
693
694 // Next pop should fail with "stack is empty".
695 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700696
697 const char kMachineProfile0[] = "machineprofile0";
698 const char kMachineProfile1[] = "machineprofile1";
699 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
700 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
701
702 // Should be able to push a machine profile.
703 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
704
705 // Should be able to push a user profile atop a machine profile.
706 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
707
708 // Pushing a system-wide profile on top of a user profile should fail.
709 EXPECT_EQ(Error::kInvalidArguments,
710 TestPushProfile(&manager, kMachineProfile1));
711
712 // However if we pop the user profile, we should be able stack another
713 // machine profile on.
714 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
715 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700716}
717
Paul Stewarte73d05c2012-03-29 16:26:05 -0700718TEST_F(ManagerTest, RemoveProfile) {
719 // It's much easier to use real Glib in creating a Manager for this
720 // test here since we want the storage side-effects.
721 GLib glib;
722 ScopedTempDir temp_dir;
723 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
724 Manager manager(control_interface(),
725 dispatcher(),
726 metrics(),
727 &glib,
728 run_path(),
729 storage_path(),
730 temp_dir.path().value());
731
732 const char kProfile0[] = "profile0";
733 FilePath profile_path(
734 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
735
736 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
737 ASSERT_TRUE(file_util::PathExists(profile_path));
738
739 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
740
741 // Remove should fail since the profile is still on the stack.
742 {
743 Error error;
744 manager.RemoveProfile(kProfile0, &error);
745 EXPECT_EQ(Error::kInvalidArguments, error.type());
746 }
747
748 // Profile path should still exist.
749 EXPECT_TRUE(file_util::PathExists(profile_path));
750
751 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
752
753 // This should succeed now that the profile is off the stack.
754 {
755 Error error;
756 manager.RemoveProfile(kProfile0, &error);
757 EXPECT_EQ(Error::kSuccess, error.type());
758 }
759
760 // Profile path should no longer exist.
761 EXPECT_FALSE(file_util::PathExists(profile_path));
762
763 // Another remove succeeds, due to a foible in file_util::Delete --
764 // it is not an error to delete a file that does not exist.
765 {
766 Error error;
767 manager.RemoveProfile(kProfile0, &error);
768 EXPECT_EQ(Error::kSuccess, error.type());
769 }
770
771 // Let's create an error case that will "work". Create a non-empty
772 // directory in the place of the profile pathname.
773 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
774 {
775 Error error;
776 manager.RemoveProfile(kProfile0, &error);
777 EXPECT_EQ(Error::kOperationFailed, error.type());
778 }
779}
780
Paul Stewart75225512012-01-26 22:51:33 -0800781// Use this matcher instead of passing RefPtrs directly into the arguments
782// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
783// system teardown.
784MATCHER_P(IsRefPtrTo, ref_address, "") {
785 return arg.get() == ref_address;
786}
787
788TEST_F(ManagerTest, HandleProfileEntryDeletion) {
789 MockServiceRefPtr s_not_in_profile(
790 new NiceMock<MockService>(control_interface(),
791 dispatcher(),
792 metrics(),
793 manager()));
794 MockServiceRefPtr s_not_in_group(
795 new NiceMock<MockService>(control_interface(),
796 dispatcher(),
797 metrics(),
798 manager()));
799 MockServiceRefPtr s_configure_fail(
800 new NiceMock<MockService>(control_interface(),
801 dispatcher(),
802 metrics(),
803 manager()));
804 MockServiceRefPtr s_configure_succeed(
805 new NiceMock<MockService>(control_interface(),
806 dispatcher(),
807 metrics(),
808 manager()));
809
810 string entry_name("entry_name");
811 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
812 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
813 .WillRepeatedly(Return("not_entry_name"));
814 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
815 .WillRepeatedly(Return(entry_name));
816 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
817 .WillRepeatedly(Return(entry_name));
818
819 manager()->RegisterService(s_not_in_profile);
820 manager()->RegisterService(s_not_in_group);
821 manager()->RegisterService(s_configure_fail);
822 manager()->RegisterService(s_configure_succeed);
823
824 scoped_refptr<MockProfile> profile0(
825 new StrictMock<MockProfile>(control_interface(), manager(), ""));
826 scoped_refptr<MockProfile> profile1(
827 new StrictMock<MockProfile>(control_interface(), manager(), ""));
828
829 s_not_in_group->set_profile(profile1);
830 s_configure_fail->set_profile(profile1);
831 s_configure_succeed->set_profile(profile1);
832
833 AdoptProfile(manager(), profile0);
834 AdoptProfile(manager(), profile1);
835
836 // No services are a member of this profile.
837 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
838
839 // No services that are members of this profile have this entry name.
840 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
841
842 // Only services that are members of the profile and group will be abandoned.
843 EXPECT_CALL(*profile1.get(),
844 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
845 EXPECT_CALL(*profile1.get(),
846 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
847 EXPECT_CALL(*profile1.get(),
848 AbandonService(IsRefPtrTo(s_configure_fail.get())))
849 .WillOnce(Return(true));
850 EXPECT_CALL(*profile1.get(),
851 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
852 .WillOnce(Return(true));
853
854 // Never allow services to re-join profile1.
855 EXPECT_CALL(*profile1.get(), ConfigureService(_))
856 .WillRepeatedly(Return(false));
857
858 // Only allow one of the members of the profile and group to successfully
859 // join profile0.
860 EXPECT_CALL(*profile0.get(),
861 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
862 EXPECT_CALL(*profile0.get(),
863 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
864 EXPECT_CALL(*profile0.get(),
865 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
866 .WillOnce(Return(false));
867 EXPECT_CALL(*profile0.get(),
868 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
869 .WillOnce(Return(true));
870
871 // Expect the failed-to-configure service to have Unload() called on it.
872 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
873 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
874 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
875 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
876
877 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
878
879 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
880 EXPECT_EQ(profile1, s_not_in_group->profile());
881 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
882
883 // Since we are using a MockProfile, the profile does not actually change,
884 // since ConfigureService was not actually called on the service.
885 EXPECT_EQ(profile1, s_configure_succeed->profile());
886}
887
Paul Stewart65512e12012-03-26 18:01:08 -0700888TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
889 MockServiceRefPtr s_will_remove0(
890 new NiceMock<MockService>(control_interface(),
891 dispatcher(),
892 metrics(),
893 manager()));
894 MockServiceRefPtr s_will_remove1(
895 new NiceMock<MockService>(control_interface(),
896 dispatcher(),
897 metrics(),
898 manager()));
899 MockServiceRefPtr s_will_not_remove0(
900 new NiceMock<MockService>(control_interface(),
901 dispatcher(),
902 metrics(),
903 manager()));
904 MockServiceRefPtr s_will_not_remove1(
905 new NiceMock<MockService>(control_interface(),
906 dispatcher(),
907 metrics(),
908 manager()));
909
910 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
911 .Times(4); // Once for each registration.
912
913 string entry_name("entry_name");
914 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
915 .WillRepeatedly(Return(entry_name));
916 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
917 .WillRepeatedly(Return(entry_name));
918 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
919 .WillRepeatedly(Return(entry_name));
920 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
921 .WillRepeatedly(Return(entry_name));
922
923 manager()->RegisterService(s_will_remove0);
924 manager()->RegisterService(s_will_not_remove0);
925 manager()->RegisterService(s_will_remove1);
926 manager()->RegisterService(s_will_not_remove1);
927
928 // One for each service added above.
929 ASSERT_EQ(4, manager()->services_.size());
930
931 scoped_refptr<MockProfile> profile(
932 new StrictMock<MockProfile>(control_interface(), manager(), ""));
933
934 s_will_remove0->set_profile(profile);
935 s_will_remove1->set_profile(profile);
936 s_will_not_remove0->set_profile(profile);
937 s_will_not_remove1->set_profile(profile);
938
939 AdoptProfile(manager(), profile);
940
941 // Deny any of the services re-entry to the profile.
942 EXPECT_CALL(*profile, ConfigureService(_))
943 .WillRepeatedly(Return(false));
944
945 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
946 .WillOnce(Return(true));
947 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
948 .WillOnce(Return(true));
949 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
950 .WillOnce(Return(true));
951 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
952 .WillOnce(Return(true));
953
954 EXPECT_CALL(*s_will_remove0, Unload())
955 .WillOnce(Return(true));
956 EXPECT_CALL(*s_will_remove1, Unload())
957 .WillOnce(Return(true));
958 EXPECT_CALL(*s_will_not_remove0, Unload())
959 .WillOnce(Return(false));
960 EXPECT_CALL(*s_will_not_remove1, Unload())
961 .WillOnce(Return(false));
962
963
964 // This will cause all the profiles to be unloaded.
965 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
966
967 // 2 of the 4 services added above should have been unregistered and
968 // removed, leaving 2.
969 EXPECT_EQ(2, manager()->services_.size());
970 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
971 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
972}
973
974TEST_F(ManagerTest, PopProfileWithUnload) {
975 MockServiceRefPtr s_will_remove0(
976 new NiceMock<MockService>(control_interface(),
977 dispatcher(),
978 metrics(),
979 manager()));
980 MockServiceRefPtr s_will_remove1(
981 new NiceMock<MockService>(control_interface(),
982 dispatcher(),
983 metrics(),
984 manager()));
985 MockServiceRefPtr s_will_not_remove0(
986 new NiceMock<MockService>(control_interface(),
987 dispatcher(),
988 metrics(),
989 manager()));
990 MockServiceRefPtr s_will_not_remove1(
991 new NiceMock<MockService>(control_interface(),
992 dispatcher(),
993 metrics(),
994 manager()));
995
996 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
997 .Times(5); // Once for each registration, and one after profile pop.
998
999 manager()->RegisterService(s_will_remove0);
1000 manager()->RegisterService(s_will_not_remove0);
1001 manager()->RegisterService(s_will_remove1);
1002 manager()->RegisterService(s_will_not_remove1);
1003
1004 // One for each service added above.
1005 ASSERT_EQ(4, manager()->services_.size());
1006
1007 scoped_refptr<MockProfile> profile0(
1008 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1009 scoped_refptr<MockProfile> profile1(
1010 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1011
1012 s_will_remove0->set_profile(profile1);
1013 s_will_remove1->set_profile(profile1);
1014 s_will_not_remove0->set_profile(profile1);
1015 s_will_not_remove1->set_profile(profile1);
1016
1017 AdoptProfile(manager(), profile0);
1018 AdoptProfile(manager(), profile1);
1019
1020 // Deny any of the services entry to profile0, so they will all be unloaded.
1021 EXPECT_CALL(*profile0, ConfigureService(_))
1022 .WillRepeatedly(Return(false));
1023
1024 EXPECT_CALL(*s_will_remove0, Unload())
1025 .WillOnce(Return(true));
1026 EXPECT_CALL(*s_will_remove1, Unload())
1027 .WillOnce(Return(true));
1028 EXPECT_CALL(*s_will_not_remove0, Unload())
1029 .WillOnce(Return(false));
1030 EXPECT_CALL(*s_will_not_remove1, Unload())
1031 .WillOnce(Return(false));
1032
1033 // This will pop profile1, which should cause all our profiles to unload.
1034 manager()->PopProfileInternal();
1035
1036 // 2 of the 4 services added above should have been unregistered and
1037 // removed, leaving 2.
1038 EXPECT_EQ(2, manager()->services_.size());
1039 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1040 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1041}
1042
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001043TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001044 {
1045 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001046 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1047 flimflam::kOfflineModeProperty,
1048 PropertyStoreTest::kBoolV,
1049 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001050 }
1051 {
1052 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001053 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1054 flimflam::kCountryProperty,
1055 PropertyStoreTest::kStringV,
1056 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001057 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001058 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001059 {
1060 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001061 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1062 flimflam::kCountryProperty,
1063 PropertyStoreTest::kBoolV,
1064 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001065 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001066 }
1067 {
1068 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001069 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1070 flimflam::kOfflineModeProperty,
1071 PropertyStoreTest::kStringV,
1072 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001073 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001074 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001075 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001076 {
1077 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001078 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001079 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001080 flimflam::kEnabledTechnologiesProperty,
1081 PropertyStoreTest::kStringsV,
1082 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001083 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001084 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001085}
1086
mukesh agrawal32399322011-09-01 10:53:43 -07001087TEST_F(ManagerTest, RequestScan) {
1088 {
1089 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001090 manager()->RegisterDevice(mock_devices_[0].get());
1091 manager()->RegisterDevice(mock_devices_[1].get());
1092 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001093 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001094 EXPECT_CALL(*mock_devices_[0], Scan(_));
1095 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001096 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001097 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001098 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001099 }
1100
1101 {
1102 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001103 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001104 EXPECT_EQ(Error::kInvalidArguments, error.type());
1105 }
1106}
1107
Darin Petkovb65c2452012-02-23 15:17:06 +01001108TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001109 KeyValueStore args;
1110 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001111 manager()->GetService(args, &e);
1112 EXPECT_EQ(Error::kInvalidArguments, e.type());
1113 EXPECT_EQ("must specify service type", e.message());
1114}
1115
1116TEST_F(ManagerTest, GetServiceUnknownType) {
1117 KeyValueStore args;
1118 Error e;
1119 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1120 manager()->GetService(args, &e);
1121 EXPECT_EQ(Error::kNotSupported, e.type());
1122 EXPECT_EQ("service type is unsupported", e.message());
1123}
1124
1125TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1126 KeyValueStore args;
1127 Error e;
1128 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1129 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001130 EXPECT_EQ(Error::kInvalidArguments, e.type());
1131 EXPECT_EQ("no wifi devices available", e.message());
1132}
1133
Darin Petkovb65c2452012-02-23 15:17:06 +01001134TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001135 KeyValueStore args;
1136 Error e;
1137 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001138 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001139 manager()->RegisterDevice(mock_wifi_);
1140 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1141 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001142 manager()->GetService(args, &e);
1143 EXPECT_TRUE(e.IsSuccess());
1144}
1145
Darin Petkov33af05c2012-02-28 10:10:30 +01001146TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1147 KeyValueStore args;
1148 Error e;
1149 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
1150 ServiceRefPtr service = manager()->GetService(args, &e);
1151 EXPECT_EQ(Error::kNotSupported, e.type());
1152 EXPECT_FALSE(service);
1153}
1154
Darin Petkovb65c2452012-02-23 15:17:06 +01001155TEST_F(ManagerTest, GetServiceVPN) {
1156 KeyValueStore args;
1157 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001158 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001159 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001160 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1161 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +01001162 ServiceRefPtr service = manager()->GetService(args, &e);
1163 EXPECT_TRUE(e.IsSuccess());
1164 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001165}
1166
Paul Stewart7f61e522012-03-22 11:13:45 -07001167TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1168 // Manager calls ActiveProfile() so we need at least one profile installed.
1169 scoped_refptr<MockProfile> profile(
1170 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1171 AdoptProfile(manager(), profile);
1172
1173 KeyValueStore args;
1174 args.SetString(flimflam::kProfileProperty, "xxx");
1175 Error error;
1176 manager()->ConfigureService(args, &error);
1177 EXPECT_EQ(Error::kInvalidArguments, error.type());
1178 EXPECT_EQ("Invalid profile name xxx", error.message());
1179}
1180
1181TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1182 // Manager calls ActiveProfile() so we need at least one profile installed.
1183 scoped_refptr<MockProfile> profile(
1184 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1185 AdoptProfile(manager(), profile);
1186
1187 KeyValueStore args;
1188 Error error;
1189 manager()->ConfigureService(args, &error);
1190 EXPECT_EQ(Error::kInvalidArguments, error.type());
1191 EXPECT_EQ("must specify service type", error.message());
1192}
1193
1194// A registered service in the ephemeral profile should be moved to the
1195// active profile as a part of configuration if no profile was explicitly
1196// specified.
1197TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1198 scoped_refptr<MockProfile> profile(
1199 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1200
1201 AdoptProfile(manager(), profile); // This is now the active profile.
1202
1203 const std::vector<uint8_t> ssid;
1204 scoped_refptr<MockWiFiService> service(
1205 new NiceMock<MockWiFiService>(control_interface(),
1206 dispatcher(),
1207 metrics(),
1208 manager(),
1209 mock_wifi_,
1210 ssid,
1211 "",
1212 "",
1213 false));
1214
1215 manager()->RegisterService(service);
1216 service->set_profile(GetEphemeralProfile(manager()));
1217
1218 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1219 // the same device as that used above causes a refcounting loop.
1220 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1221 dispatcher(),
1222 metrics(),
1223 manager(),
1224 "wifi1",
1225 "addr5",
1226 5));
1227 manager()->RegisterDevice(wifi);
1228 EXPECT_CALL(*wifi, GetService(_, _))
1229 .WillOnce(Return(service));
1230 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1231 .WillOnce(Return(true));
1232 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1233 .WillOnce(Return(true));
1234
1235 KeyValueStore args;
1236 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1237 Error error;
1238 manager()->ConfigureService(args, &error);
1239 EXPECT_TRUE(error.IsSuccess());
1240}
1241
1242// If were configure a service that was already registered and explicitly
1243// specify a profile, it should be moved from the profile it was previously
1244// in to the specified profile if one was requested.
1245TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1246 scoped_refptr<MockProfile> profile0(
1247 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1248 scoped_refptr<MockProfile> profile1(
1249 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1250
1251 const string kProfileName0 = "profile0";
1252 const string kProfileName1 = "profile1";
1253
1254 EXPECT_CALL(*profile0, GetRpcIdentifier())
1255 .WillRepeatedly(Return(kProfileName0));
1256 EXPECT_CALL(*profile1, GetRpcIdentifier())
1257 .WillRepeatedly(Return(kProfileName1));
1258
1259 AdoptProfile(manager(), profile0);
1260 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1261
1262 const std::vector<uint8_t> ssid;
1263 scoped_refptr<MockWiFiService> service(
1264 new NiceMock<MockWiFiService>(control_interface(),
1265 dispatcher(),
1266 metrics(),
1267 manager(),
1268 mock_wifi_,
1269 ssid,
1270 "",
1271 "",
1272 false));
1273
1274 manager()->RegisterService(service);
1275 service->set_profile(profile1);
1276
1277 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1278 // the same device as that used above causes a refcounting loop.
1279 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1280 dispatcher(),
1281 metrics(),
1282 manager(),
1283 "wifi1",
1284 "addr5",
1285 5));
1286 manager()->RegisterDevice(wifi);
1287 EXPECT_CALL(*wifi, GetService(_, _))
1288 .WillOnce(Return(service));
1289 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1290 .WillOnce(Return(true));
1291 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1292 .WillOnce(Return(true));
1293 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1294 .WillOnce(Return(true));
1295
1296 KeyValueStore args;
1297 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1298 args.SetString(flimflam::kProfileProperty, kProfileName0);
1299 Error error;
1300 manager()->ConfigureService(args, &error);
1301 EXPECT_TRUE(error.IsSuccess());
1302 service->set_profile(NULL); // Breaks refcounting loop.
1303}
1304
1305// An unregistered service should remain unregistered, but its contents should
1306// be saved to the specified profile nonetheless.
1307TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1308 scoped_refptr<MockProfile> profile0(
1309 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1310 scoped_refptr<MockProfile> profile1(
1311 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1312
1313 const string kProfileName0 = "profile0";
1314 const string kProfileName1 = "profile1";
1315
1316 EXPECT_CALL(*profile0, GetRpcIdentifier())
1317 .WillRepeatedly(Return(kProfileName0));
1318 EXPECT_CALL(*profile1, GetRpcIdentifier())
1319 .WillRepeatedly(Return(kProfileName1));
1320
1321 AdoptProfile(manager(), profile0);
1322 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1323
1324 const std::vector<uint8_t> ssid;
1325 scoped_refptr<MockWiFiService> service(
1326 new NiceMock<MockWiFiService>(control_interface(),
1327 dispatcher(),
1328 metrics(),
1329 manager(),
1330 mock_wifi_,
1331 ssid,
1332 "",
1333 "",
1334 false));
1335
1336 service->set_profile(profile1);
1337
1338 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1339 // the same device as that used above causes a refcounting loop.
1340 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1341 dispatcher(),
1342 metrics(),
1343 manager(),
1344 "wifi1",
1345 "addr5",
1346 5));
1347 manager()->RegisterDevice(wifi);
1348 EXPECT_CALL(*wifi, GetService(_, _))
1349 .WillOnce(Return(service));
1350 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1351 .WillOnce(Return(true));
1352 EXPECT_CALL(*profile0, AdoptService(_))
1353 .Times(0);
1354 EXPECT_CALL(*profile1, AdoptService(_))
1355 .Times(0);
1356
1357 KeyValueStore args;
1358 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1359 args.SetString(flimflam::kProfileProperty, kProfileName0);
1360 Error error;
1361 manager()->ConfigureService(args, &error);
1362 EXPECT_TRUE(error.IsSuccess());
1363}
1364
Paul Stewart22aa71b2011-09-16 12:15:11 -07001365TEST_F(ManagerTest, TechnologyOrder) {
1366 Error error;
1367 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1368 string(flimflam::kTypeWifi), &error);
1369 ASSERT_TRUE(error.IsSuccess());
1370 EXPECT_EQ(manager()->GetTechnologyOrder(),
1371 string(flimflam::kTypeEthernet) + "," +
1372 string(flimflam::kTypeWifi));
1373
1374 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1375 string(flimflam::kTypeWifi), &error);
1376 ASSERT_FALSE(error.IsSuccess());
1377 EXPECT_EQ(Error::kInvalidArguments, error.type());
1378 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1379 string(flimflam::kTypeWifi),
1380 manager()->GetTechnologyOrder());
1381}
1382
1383TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001384 // TODO(quiche): Some of these tests would probably fit better in
1385 // service_unittest, since the actual comparison of Services is
1386 // implemented in Service. (crosbug.com/23370)
1387
Paul Stewart22aa71b2011-09-16 12:15:11 -07001388 scoped_refptr<MockService> mock_service0(
1389 new NiceMock<MockService>(control_interface(),
1390 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001391 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001392 manager()));
1393 scoped_refptr<MockService> mock_service1(
1394 new NiceMock<MockService>(control_interface(),
1395 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001396 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001397 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001398
1399 manager()->RegisterService(mock_service0);
1400 manager()->RegisterService(mock_service1);
1401
1402 // Services should already be sorted by UniqueName
1403 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1404
1405 // Asking explictly to sort services should not change anything
1406 manager()->SortServices();
1407 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1408
1409 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001410 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001411 manager()->UpdateService(mock_service1);
1412 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1413
1414 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001415 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001416 manager()->UpdateService(mock_service0);
1417 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1418
1419 // Technology
1420 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1421 .WillRepeatedly(Return(true));
1422 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1423 .WillRepeatedly(Return(true));
1424 // NB: Redefine default (false) return values so we don't use the default rule
1425 // which makes the logs noisier
1426 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1427 .WillRepeatedly(Return(false));
1428 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1429 .WillRepeatedly(Return(false));
1430
1431 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001432 // Default technology ordering should favor Ethernet over WiFi.
1433 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001434 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1435
1436 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1437 string(flimflam::kTypeEthernet), &error);
1438 EXPECT_TRUE(error.IsSuccess());
1439 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1440
Gaurav Shah435de2c2011-11-17 19:01:07 -08001441 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001442 mock_service0->set_priority(1);
1443 manager()->UpdateService(mock_service0);
1444 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1445
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001446 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001447 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001448 manager()->UpdateService(mock_service1);
1449 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1450
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001451 // Auto-connect.
1452 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001453 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001454 mock_service1->set_auto_connect(false);
1455 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001456 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1457
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001458 // Connectable.
1459 mock_service1->set_connectable(true);
1460 manager()->UpdateService(mock_service1);
1461 mock_service0->set_connectable(false);
1462 manager()->UpdateService(mock_service0);
1463 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1464
1465 // IsFailed.
1466 EXPECT_CALL(*mock_service0.get(), state())
1467 .WillRepeatedly(Return(Service::kStateIdle));
1468 EXPECT_CALL(*mock_service0.get(), IsFailed())
1469 .WillRepeatedly(Return(false));
1470 manager()->UpdateService(mock_service0);
1471 EXPECT_CALL(*mock_service0.get(), state())
1472 .WillRepeatedly(Return(Service::kStateFailure));
1473 EXPECT_CALL(*mock_service1.get(), IsFailed())
1474 .WillRepeatedly(Return(true));
1475 manager()->UpdateService(mock_service1);
1476 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1477
1478 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001479 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001480 .WillRepeatedly(Return(Service::kStateAssociating));
1481 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001482 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001483 manager()->UpdateService(mock_service1);
1484 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1485
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001486 // Connected.
1487 EXPECT_CALL(*mock_service0.get(), state())
1488 .WillRepeatedly(Return(Service::kStateConnected));
1489 EXPECT_CALL(*mock_service0.get(), IsConnected())
1490 .WillRepeatedly(Return(true));
1491 manager()->UpdateService(mock_service0);
1492 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1493
Paul Stewart22aa71b2011-09-16 12:15:11 -07001494 manager()->DeregisterService(mock_service0);
1495 manager()->DeregisterService(mock_service1);
1496}
1497
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001498TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001499 MockMetrics mock_metrics;
1500 manager()->set_metrics(&mock_metrics);
1501
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001502 scoped_refptr<MockService> mock_service0(
1503 new NiceMock<MockService>(control_interface(),
1504 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001505 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001506 manager()));
1507 scoped_refptr<MockService> mock_service1(
1508 new NiceMock<MockService>(control_interface(),
1509 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001510 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001511 manager()));
1512
1513 scoped_refptr<MockConnection> mock_connection0(
1514 new NiceMock<MockConnection>(device_info_.get()));
1515 scoped_refptr<MockConnection> mock_connection1(
1516 new NiceMock<MockConnection>(device_info_.get()));
1517
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001518 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001519 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001520 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001521 manager()->RegisterService(mock_service1);
1522
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001523 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1524 manager()->SortServices();
1525
1526 mock_service1->set_priority(1);
1527 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1528 manager()->SortServices();
1529
1530 mock_service1->set_priority(0);
1531 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1532 manager()->SortServices();
1533
Paul Stewartce4ec192012-03-14 12:53:46 -07001534 mock_service0->set_mock_connection(mock_connection0);
1535 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001536
1537 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001538 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001539 manager()->SortServices();
1540
1541 mock_service1->set_priority(1);
1542 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1543 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001544 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001545 manager()->SortServices();
1546
1547 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001548 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001549 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001550 manager()->DeregisterService(mock_service1);
1551
Paul Stewartce4ec192012-03-14 12:53:46 -07001552 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001553 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001554 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001555
1556 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1557 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001558}
1559
Gaurav Shah435de2c2011-11-17 19:01:07 -08001560TEST_F(ManagerTest, AvailableTechnologies) {
1561 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1562 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001563 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001564 manager(),
1565 "null4",
1566 "addr4",
1567 0));
1568 manager()->RegisterDevice(mock_devices_[0]);
1569 manager()->RegisterDevice(mock_devices_[1]);
1570 manager()->RegisterDevice(mock_devices_[2]);
1571 manager()->RegisterDevice(mock_devices_[3]);
1572
1573 ON_CALL(*mock_devices_[0].get(), technology())
1574 .WillByDefault(Return(Technology::kEthernet));
1575 ON_CALL(*mock_devices_[1].get(), technology())
1576 .WillByDefault(Return(Technology::kWifi));
1577 ON_CALL(*mock_devices_[2].get(), technology())
1578 .WillByDefault(Return(Technology::kCellular));
1579 ON_CALL(*mock_devices_[3].get(), technology())
1580 .WillByDefault(Return(Technology::kWifi));
1581
1582 set<string> expected_technologies;
1583 expected_technologies.insert(Technology::NameFromIdentifier(
1584 Technology::kEthernet));
1585 expected_technologies.insert(Technology::NameFromIdentifier(
1586 Technology::kWifi));
1587 expected_technologies.insert(Technology::NameFromIdentifier(
1588 Technology::kCellular));
1589 Error error;
1590 vector<string> technologies = manager()->AvailableTechnologies(&error);
1591
1592 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1593 ContainerEq(expected_technologies));
1594}
1595
1596TEST_F(ManagerTest, ConnectedTechnologies) {
1597 scoped_refptr<MockService> connected_service1(
1598 new NiceMock<MockService>(control_interface(),
1599 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001600 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001601 manager()));
1602 scoped_refptr<MockService> connected_service2(
1603 new NiceMock<MockService>(control_interface(),
1604 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001605 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001606 manager()));
1607 scoped_refptr<MockService> disconnected_service1(
1608 new NiceMock<MockService>(control_interface(),
1609 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001610 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001611 manager()));
1612 scoped_refptr<MockService> disconnected_service2(
1613 new NiceMock<MockService>(control_interface(),
1614 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001615 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001616 manager()));
1617
1618 ON_CALL(*connected_service1.get(), IsConnected())
1619 .WillByDefault(Return(true));
1620 ON_CALL(*connected_service2.get(), IsConnected())
1621 .WillByDefault(Return(true));
1622
1623 manager()->RegisterService(connected_service1);
1624 manager()->RegisterService(connected_service2);
1625 manager()->RegisterService(disconnected_service1);
1626 manager()->RegisterService(disconnected_service2);
1627
1628 manager()->RegisterDevice(mock_devices_[0]);
1629 manager()->RegisterDevice(mock_devices_[1]);
1630 manager()->RegisterDevice(mock_devices_[2]);
1631 manager()->RegisterDevice(mock_devices_[3]);
1632
1633 ON_CALL(*mock_devices_[0].get(), technology())
1634 .WillByDefault(Return(Technology::kEthernet));
1635 ON_CALL(*mock_devices_[1].get(), technology())
1636 .WillByDefault(Return(Technology::kWifi));
1637 ON_CALL(*mock_devices_[2].get(), technology())
1638 .WillByDefault(Return(Technology::kCellular));
1639 ON_CALL(*mock_devices_[3].get(), technology())
1640 .WillByDefault(Return(Technology::kWifi));
1641
1642 mock_devices_[0]->SelectService(connected_service1);
1643 mock_devices_[1]->SelectService(disconnected_service1);
1644 mock_devices_[2]->SelectService(disconnected_service2);
1645 mock_devices_[3]->SelectService(connected_service2);
1646
1647 set<string> expected_technologies;
1648 expected_technologies.insert(Technology::NameFromIdentifier(
1649 Technology::kEthernet));
1650 expected_technologies.insert(Technology::NameFromIdentifier(
1651 Technology::kWifi));
1652 Error error;
1653
1654 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1655 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1656 ContainerEq(expected_technologies));
1657}
1658
1659TEST_F(ManagerTest, DefaultTechnology) {
1660 scoped_refptr<MockService> connected_service(
1661 new NiceMock<MockService>(control_interface(),
1662 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001663 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001664 manager()));
1665 scoped_refptr<MockService> disconnected_service(
1666 new NiceMock<MockService>(control_interface(),
1667 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001668 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001669 manager()));
1670
1671 // Connected. WiFi.
1672 ON_CALL(*connected_service.get(), IsConnected())
1673 .WillByDefault(Return(true));
1674 ON_CALL(*connected_service.get(), state())
1675 .WillByDefault(Return(Service::kStateConnected));
1676 ON_CALL(*connected_service.get(), technology())
1677 .WillByDefault(Return(Technology::kWifi));
1678
1679 // Disconnected. Ethernet.
1680 ON_CALL(*disconnected_service.get(), technology())
1681 .WillByDefault(Return(Technology::kEthernet));
1682
1683 manager()->RegisterService(disconnected_service);
1684 Error error;
1685 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1686
1687
1688 manager()->RegisterService(connected_service);
1689 // Connected service should be brought to the front now.
1690 string expected_technology =
1691 Technology::NameFromIdentifier(Technology::kWifi);
1692 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1693}
1694
Thieu Le1271d682011-11-02 22:48:19 +00001695TEST_F(ManagerTest, DisconnectServicesOnStop) {
1696 scoped_refptr<MockService> mock_service(
1697 new NiceMock<MockService>(control_interface(),
1698 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001699 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001700 manager()));
1701 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001702 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001703 manager()->Stop();
1704}
1705
mukesh agrawal00917ce2011-11-22 23:56:55 +00001706TEST_F(ManagerTest, UpdateServiceConnected) {
1707 scoped_refptr<MockService> mock_service(
1708 new NiceMock<MockService>(control_interface(),
1709 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001710 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001711 manager()));
1712 manager()->RegisterService(mock_service);
1713 EXPECT_FALSE(mock_service->favorite());
1714 EXPECT_FALSE(mock_service->auto_connect());
1715
Gaurav Shah435de2c2011-11-17 19:01:07 -08001716 EXPECT_CALL(*mock_service.get(), IsConnected())
1717 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001718 manager()->UpdateService(mock_service);
1719 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1720 // to mock out MakeFavorite. And mocking that out would break the
1721 // SortServices test. (crosbug.com/23370)
1722 EXPECT_TRUE(mock_service->favorite());
1723 EXPECT_TRUE(mock_service->auto_connect());
1724}
1725
Thieu Led4e9e552012-02-16 16:26:07 -08001726TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1727 // This tests the case where the user connects to a service that is
1728 // currently associated with a profile. We want to make sure that the
1729 // favorite flag is set and that the flag is saved to the current
1730 // profile.
1731 scoped_refptr<MockService> mock_service(
1732 new NiceMock<MockService>(control_interface(),
1733 dispatcher(),
1734 metrics(),
1735 manager()));
1736 manager()->RegisterService(mock_service);
1737 EXPECT_FALSE(mock_service->favorite());
1738 EXPECT_FALSE(mock_service->auto_connect());
1739
1740 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1741 mock_service->set_profile(profile);
1742
1743 EXPECT_CALL(*mock_service.get(), IsConnected())
1744 .WillRepeatedly(Return(true));
1745 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1746 manager()->UpdateService(mock_service);
1747 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1748 // to mock out MakeFavorite. And mocking that out would break the
1749 // SortServices test. (crosbug.com/23370)
1750 EXPECT_TRUE(mock_service->favorite());
1751 EXPECT_TRUE(mock_service->auto_connect());
1752}
1753
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001754TEST_F(ManagerTest, SaveSuccessfulService) {
1755 scoped_refptr<MockProfile> profile(
1756 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1757 AdoptProfile(manager(), profile);
1758 scoped_refptr<MockService> service(
1759 new NiceMock<MockService>(control_interface(),
1760 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001761 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001762 manager()));
1763
1764 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1765 ServiceRefPtr expect_service(service.get());
1766
1767 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1768 .WillOnce(Return(false));
1769 manager()->RegisterService(service);
1770
1771 EXPECT_CALL(*service.get(), state())
1772 .WillRepeatedly(Return(Service::kStateConnected));
1773 EXPECT_CALL(*service.get(), IsConnected())
1774 .WillRepeatedly(Return(true));
1775 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1776 .WillOnce(Return(true));
1777 manager()->UpdateService(service);
1778}
1779
Paul Stewart1b253142012-01-26 14:05:52 -08001780TEST_F(ManagerTest, EnumerateProfiles) {
1781 vector<string> profile_paths;
1782 for (size_t i = 0; i < 10; i++) {
1783 scoped_refptr<MockProfile> profile(
1784 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001785 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001786 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1787 .WillOnce(Return(profile_paths.back()));
1788 AdoptProfile(manager(), profile);
1789 }
1790
1791 Error error;
1792 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1793 EXPECT_TRUE(error.IsSuccess());
1794 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1795 for (size_t i = 0; i < profile_paths.size(); i++) {
1796 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1797 }
1798}
1799
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001800TEST_F(ManagerTest, AutoConnectOnRegister) {
1801 MockServiceRefPtr service = MakeAutoConnectableService();
1802 EXPECT_CALL(*service.get(), AutoConnect());
1803 manager()->RegisterService(service);
1804 dispatcher()->DispatchPendingEvents();
1805}
1806
1807TEST_F(ManagerTest, AutoConnectOnUpdate) {
1808 MockServiceRefPtr service1 = MakeAutoConnectableService();
1809 service1->set_priority(1);
1810 MockServiceRefPtr service2 = MakeAutoConnectableService();
1811 service2->set_priority(2);
1812 manager()->RegisterService(service1);
1813 manager()->RegisterService(service2);
1814 dispatcher()->DispatchPendingEvents();
1815
1816 EXPECT_CALL(*service1.get(), AutoConnect());
1817 EXPECT_CALL(*service2.get(), state())
1818 .WillRepeatedly(Return(Service::kStateFailure));
1819 EXPECT_CALL(*service2.get(), IsFailed())
1820 .WillRepeatedly(Return(true));
1821 EXPECT_CALL(*service2.get(), IsConnected())
1822 .WillRepeatedly(Return(false));
1823 manager()->UpdateService(service2);
1824 dispatcher()->DispatchPendingEvents();
1825}
1826
1827TEST_F(ManagerTest, AutoConnectOnDeregister) {
1828 MockServiceRefPtr service1 = MakeAutoConnectableService();
1829 service1->set_priority(1);
1830 MockServiceRefPtr service2 = MakeAutoConnectableService();
1831 service2->set_priority(2);
1832 manager()->RegisterService(service1);
1833 manager()->RegisterService(service2);
1834 dispatcher()->DispatchPendingEvents();
1835
1836 EXPECT_CALL(*service1.get(), AutoConnect());
1837 manager()->DeregisterService(service2);
1838 dispatcher()->DispatchPendingEvents();
1839}
1840
Paul Stewartc681fa02012-03-02 19:40:04 -08001841TEST_F(ManagerTest, RecheckPortal) {
1842 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1843 .WillOnce(Return(false));
1844 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1845 .WillOnce(Return(true));
1846 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1847 .Times(0);
1848
1849 manager()->RegisterDevice(mock_devices_[0]);
1850 manager()->RegisterDevice(mock_devices_[1]);
1851 manager()->RegisterDevice(mock_devices_[2]);
1852
1853 manager()->RecheckPortal(NULL);
1854}
1855
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001856TEST_F(ManagerTest, GetDefaultService) {
1857 EXPECT_FALSE(manager()->GetDefaultService().get());
1858
1859 scoped_refptr<MockService> mock_service(
1860 new NiceMock<MockService>(control_interface(),
1861 dispatcher(),
1862 metrics(),
1863 manager()));
1864
1865 manager()->RegisterService(mock_service);
1866 EXPECT_FALSE(manager()->GetDefaultService().get());
1867
1868 scoped_refptr<MockConnection> mock_connection(
1869 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001870 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001871 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1872
Paul Stewartce4ec192012-03-14 12:53:46 -07001873 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001874 manager()->DeregisterService(mock_service);
1875}
1876
Paul Stewart13ed2252012-03-21 12:52:46 -07001877TEST_F(ManagerTest, GetServiceWithGUID) {
1878 scoped_refptr<MockService> mock_service0(
1879 new NiceMock<MockService>(control_interface(),
1880 dispatcher(),
1881 metrics(),
1882 manager()));
1883
1884 scoped_refptr<MockService> mock_service1(
1885 new NiceMock<MockService>(control_interface(),
1886 dispatcher(),
1887 metrics(),
1888 manager()));
1889
Paul Stewartcb59fed2012-03-21 21:14:46 -07001890 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1891 .Times(0);
1892 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1893 .Times(0);
1894
Paul Stewart13ed2252012-03-21 12:52:46 -07001895 manager()->RegisterService(mock_service0);
1896 manager()->RegisterService(mock_service1);
1897
1898 const string kGUID0 = "GUID0";
1899 const string kGUID1 = "GUID1";
1900
1901 {
1902 Error error;
1903 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1904 EXPECT_FALSE(error.IsSuccess());
1905 EXPECT_FALSE(service);
1906 }
1907
1908 KeyValueStore args;
1909 args.SetString(flimflam::kGuidProperty, kGUID1);
1910
1911 {
1912 Error error;
1913 ServiceRefPtr service = manager()->GetService(args, &error);
1914 EXPECT_EQ(Error::kInvalidArguments, error.type());
1915 EXPECT_FALSE(service);
1916 }
1917
1918 mock_service0->set_guid(kGUID0);
1919 mock_service1->set_guid(kGUID1);
1920
1921 {
1922 Error error;
1923 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1924 EXPECT_TRUE(error.IsSuccess());
1925 EXPECT_EQ(mock_service0.get(), service.get());
1926 }
1927
1928 {
1929 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07001930 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
1931 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07001932 ServiceRefPtr service = manager()->GetService(args, &error);
1933 EXPECT_TRUE(error.IsSuccess());
1934 EXPECT_EQ(mock_service1.get(), service.get());
1935 }
1936
1937 manager()->DeregisterService(mock_service0);
1938 manager()->DeregisterService(mock_service1);
1939}
1940
Gary Morain028545d2012-04-07 14:55:52 -07001941
1942TEST_F(ManagerTest, CalculateStateOffline) {
1943 MockMetrics mock_metrics;
1944 manager()->set_metrics(&mock_metrics);
1945 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
1946 .Times(AnyNumber());
1947 scoped_refptr<MockService> mock_service0(
1948 new NiceMock<MockService>(control_interface(),
1949 dispatcher(),
1950 metrics(),
1951 manager()));
1952
1953 scoped_refptr<MockService> mock_service1(
1954 new NiceMock<MockService>(control_interface(),
1955 dispatcher(),
1956 metrics(),
1957 manager()));
1958
1959 EXPECT_CALL(*mock_service0.get(), IsConnected())
1960 .WillRepeatedly(Return(false));
1961 EXPECT_CALL(*mock_service1.get(), IsConnected())
1962 .WillRepeatedly(Return(false));
1963
1964 manager()->RegisterService(mock_service0);
1965 manager()->RegisterService(mock_service1);
1966
1967 EXPECT_EQ("offline", manager()->CalculateState(NULL));
1968
1969 manager()->DeregisterService(mock_service0);
1970 manager()->DeregisterService(mock_service1);
1971}
1972
1973TEST_F(ManagerTest, CalculateStateOnline) {
1974 MockMetrics mock_metrics;
1975 manager()->set_metrics(&mock_metrics);
1976 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
1977 .Times(AnyNumber());
1978 scoped_refptr<MockService> mock_service0(
1979 new NiceMock<MockService>(control_interface(),
1980 dispatcher(),
1981 metrics(),
1982 manager()));
1983
1984 scoped_refptr<MockService> mock_service1(
1985 new NiceMock<MockService>(control_interface(),
1986 dispatcher(),
1987 metrics(),
1988 manager()));
1989
1990 EXPECT_CALL(*mock_service0.get(), IsConnected())
1991 .WillRepeatedly(Return(false));
1992 EXPECT_CALL(*mock_service1.get(), IsConnected())
1993 .WillRepeatedly(Return(true));
1994 EXPECT_CALL(*mock_service0.get(), state())
1995 .WillRepeatedly(Return(Service::kStateIdle));
1996 EXPECT_CALL(*mock_service1.get(), state())
1997 .WillRepeatedly(Return(Service::kStateConnected));
1998
1999 manager()->RegisterService(mock_service0);
2000 manager()->RegisterService(mock_service1);
2001
2002 EXPECT_EQ("online", manager()->CalculateState(NULL));
2003
2004 manager()->DeregisterService(mock_service0);
2005 manager()->DeregisterService(mock_service1);
2006}
2007
Chris Masone9be4a9d2011-05-16 15:44:09 -07002008} // namespace shill