blob: 83628828bd356c32312610cb009899c335f03875 [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 // Say we don't have |s2| the first time asked, then that we do.
479 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
480 .WillOnce(Return(false))
481 .WillRepeatedly(Return(true));
482 EXPECT_CALL(*storage, Flush())
483 .Times(AnyNumber())
484 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700485 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700486 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700487 }
Chris Masone6515aab2011-10-12 16:19:09 -0700488 // Create a profile that already has |s2| in it.
489 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
490 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700491
Chris Masone6515aab2011-10-12 16:19:09 -0700492 // Now, move the Service |s2| to another profile.
493 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
494 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700495
496 // Force destruction of the original Profile, to ensure that the Service
497 // is kept alive and populated with data.
498 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700499 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700500 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700501}
502
Paul Stewart7f61e522012-03-22 11:13:45 -0700503TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
504 scoped_refptr<MockProfile> mock_profile(
505 new MockProfile(control_interface(), manager(), ""));
506 const string kProfileName("profile0");
507 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
508 .WillRepeatedly(Return(kProfileName));
509 AdoptProfile(manager(), mock_profile);
510
511 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
512 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
513 EXPECT_EQ(mock_profile.get(), profile.get());
514}
515
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800516TEST_F(ManagerTest, SetProfileForService) {
517 scoped_refptr<MockProfile> profile0(
518 new MockProfile(control_interface(), manager(), ""));
519 string profile_name0("profile0");
520 EXPECT_CALL(*profile0, GetRpcIdentifier())
521 .WillRepeatedly(Return(profile_name0));
522 AdoptProfile(manager(), profile0);
523 scoped_refptr<MockService> service(new MockService(control_interface(),
524 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800525 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800526 manager()));
527 service->set_profile(profile0);
528
529 {
530 Error error;
531 manager()->SetProfileForService(service, "foo", &error);
532 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700533 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800534 }
535
536 {
537 Error error;
538 manager()->SetProfileForService(service, profile_name0, &error);
539 EXPECT_EQ(Error::kInvalidArguments, error.type());
540 EXPECT_EQ("Service is already connected to this profile", error.message());
541 }
542
543 scoped_refptr<MockProfile> profile1(
544 new MockProfile(control_interface(), manager(), ""));
545 string profile_name1("profile1");
546 EXPECT_CALL(*profile1, GetRpcIdentifier())
547 .WillRepeatedly(Return(profile_name1));
548 AdoptProfile(manager(), profile1);
549
550 {
551 Error error;
552 EXPECT_CALL(*profile1, AdoptService(_))
553 .WillOnce(Return(true));
554 EXPECT_CALL(*profile0, AbandonService(_))
555 .WillOnce(Return(true));
556 manager()->SetProfileForService(service, profile_name1, &error);
557 EXPECT_TRUE(error.IsSuccess());
558 }
559}
560
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700561TEST_F(ManagerTest, CreateProfile) {
562 // It's much easier to use real Glib here since we want the storage
563 // side-effects.
564 GLib glib;
565 ScopedTempDir temp_dir;
566 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
567
568 Manager manager(control_interface(),
569 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800570 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700571 &glib,
572 run_path(),
573 storage_path(),
574 temp_dir.path().value());
575
576 // Invalid name should be rejected.
577 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
578
Paul Stewartd0a3b812012-03-28 22:48:22 -0700579 // A profile with invalid characters in it should similarly be rejected.
580 EXPECT_EQ(Error::kInvalidArguments,
581 TestCreateProfile(&manager, "valid_profile"));
582
583 // We should be able to create a machine profile.
584 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700585
586 // We should succeed in creating a valid user profile.
587 const char kProfile[] = "~user/profile";
588 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
589
590 // We should fail in creating it a second time (already exists).
591 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
592}
593
594TEST_F(ManagerTest, PushPopProfile) {
595 // It's much easier to use real Glib in creating a Manager for this
596 // test here since we want the storage side-effects.
597 GLib glib;
598 ScopedTempDir temp_dir;
599 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
600 Manager manager(control_interface(),
601 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800602 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700603 &glib,
604 run_path(),
605 storage_path(),
606 temp_dir.path().value());
607
608 // Pushing an invalid profile should fail.
609 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
610
Paul Stewartd0a3b812012-03-28 22:48:22 -0700611 // Pushing a default profile that does not exist should fail.
612 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700613
614 const char kProfile0[] = "~user/profile0";
615 const char kProfile1[] = "~user/profile1";
616
617 // Create a couple of profiles.
618 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
619 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
620
621 // Push these profiles on the stack.
622 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
623 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
624
625 // Pushing a profile a second time should fail.
626 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
627 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
628
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800629 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700630 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800631 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700632
633 // Make sure a profile name that doesn't exist fails.
634 const char kProfile2Id[] = "profile2";
635 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
636 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
637
638 // Create a new service, with a specific storage name.
639 scoped_refptr<MockService> service(
640 new NiceMock<MockService>(control_interface(),
641 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800642 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700643 &manager));
644 const char kServiceName[] = "service_storage_name";
645 EXPECT_CALL(*service.get(), GetStorageIdentifier())
646 .WillRepeatedly(Return(kServiceName));
647 EXPECT_CALL(*service.get(), Load(_))
648 .WillRepeatedly(Return(true));
649
650 // Add this service to the manager -- it should end up in the ephemeral
651 // profile.
652 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800653 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700654
655 // Create storage for a profile that contains the service storage name.
656 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
657 kServiceName));
658
659 // When we push the profile, the service should move away from the
660 // ephemeral profile to this new profile since it has an entry for
661 // this service.
662 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800663 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700664 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
665
666 // Insert another profile that should supersede ownership of the service.
667 const char kProfile3Id[] = "profile3";
668 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
669 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
670 kServiceName));
671 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
672 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
673
674 // Popping an invalid profile name should fail.
675 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
676
677 // Popping an profile that is not at the top of the stack should fail.
678 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
679
680 // Popping the top profile should succeed.
681 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
682
683 // Moreover the service should have switched profiles to profile 2.
684 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
685
686 // Popping the top profile should succeed.
687 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
688
689 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800690 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700691
692 // Pop the remaining two services off the stack.
693 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
694 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
695
696 // Next pop should fail with "stack is empty".
697 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700698
699 const char kMachineProfile0[] = "machineprofile0";
700 const char kMachineProfile1[] = "machineprofile1";
701 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
702 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
703
704 // Should be able to push a machine profile.
705 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
706
707 // Should be able to push a user profile atop a machine profile.
708 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
709
710 // Pushing a system-wide profile on top of a user profile should fail.
711 EXPECT_EQ(Error::kInvalidArguments,
712 TestPushProfile(&manager, kMachineProfile1));
713
714 // However if we pop the user profile, we should be able stack another
715 // machine profile on.
716 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
717 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700718}
719
Paul Stewarte73d05c2012-03-29 16:26:05 -0700720TEST_F(ManagerTest, RemoveProfile) {
721 // It's much easier to use real Glib in creating a Manager for this
722 // test here since we want the storage side-effects.
723 GLib glib;
724 ScopedTempDir temp_dir;
725 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
726 Manager manager(control_interface(),
727 dispatcher(),
728 metrics(),
729 &glib,
730 run_path(),
731 storage_path(),
732 temp_dir.path().value());
733
734 const char kProfile0[] = "profile0";
735 FilePath profile_path(
736 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
737
738 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
739 ASSERT_TRUE(file_util::PathExists(profile_path));
740
741 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
742
743 // Remove should fail since the profile is still on the stack.
744 {
745 Error error;
746 manager.RemoveProfile(kProfile0, &error);
747 EXPECT_EQ(Error::kInvalidArguments, error.type());
748 }
749
750 // Profile path should still exist.
751 EXPECT_TRUE(file_util::PathExists(profile_path));
752
753 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
754
755 // This should succeed now that the profile is off the stack.
756 {
757 Error error;
758 manager.RemoveProfile(kProfile0, &error);
759 EXPECT_EQ(Error::kSuccess, error.type());
760 }
761
762 // Profile path should no longer exist.
763 EXPECT_FALSE(file_util::PathExists(profile_path));
764
765 // Another remove succeeds, due to a foible in file_util::Delete --
766 // it is not an error to delete a file that does not exist.
767 {
768 Error error;
769 manager.RemoveProfile(kProfile0, &error);
770 EXPECT_EQ(Error::kSuccess, error.type());
771 }
772
773 // Let's create an error case that will "work". Create a non-empty
774 // directory in the place of the profile pathname.
775 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
776 {
777 Error error;
778 manager.RemoveProfile(kProfile0, &error);
779 EXPECT_EQ(Error::kOperationFailed, error.type());
780 }
781}
782
Paul Stewart75225512012-01-26 22:51:33 -0800783// Use this matcher instead of passing RefPtrs directly into the arguments
784// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
785// system teardown.
786MATCHER_P(IsRefPtrTo, ref_address, "") {
787 return arg.get() == ref_address;
788}
789
790TEST_F(ManagerTest, HandleProfileEntryDeletion) {
791 MockServiceRefPtr s_not_in_profile(
792 new NiceMock<MockService>(control_interface(),
793 dispatcher(),
794 metrics(),
795 manager()));
796 MockServiceRefPtr s_not_in_group(
797 new NiceMock<MockService>(control_interface(),
798 dispatcher(),
799 metrics(),
800 manager()));
801 MockServiceRefPtr s_configure_fail(
802 new NiceMock<MockService>(control_interface(),
803 dispatcher(),
804 metrics(),
805 manager()));
806 MockServiceRefPtr s_configure_succeed(
807 new NiceMock<MockService>(control_interface(),
808 dispatcher(),
809 metrics(),
810 manager()));
811
812 string entry_name("entry_name");
813 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
814 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
815 .WillRepeatedly(Return("not_entry_name"));
816 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
817 .WillRepeatedly(Return(entry_name));
818 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
819 .WillRepeatedly(Return(entry_name));
820
821 manager()->RegisterService(s_not_in_profile);
822 manager()->RegisterService(s_not_in_group);
823 manager()->RegisterService(s_configure_fail);
824 manager()->RegisterService(s_configure_succeed);
825
826 scoped_refptr<MockProfile> profile0(
827 new StrictMock<MockProfile>(control_interface(), manager(), ""));
828 scoped_refptr<MockProfile> profile1(
829 new StrictMock<MockProfile>(control_interface(), manager(), ""));
830
831 s_not_in_group->set_profile(profile1);
832 s_configure_fail->set_profile(profile1);
833 s_configure_succeed->set_profile(profile1);
834
835 AdoptProfile(manager(), profile0);
836 AdoptProfile(manager(), profile1);
837
838 // No services are a member of this profile.
839 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
840
841 // No services that are members of this profile have this entry name.
842 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
843
844 // Only services that are members of the profile and group will be abandoned.
845 EXPECT_CALL(*profile1.get(),
846 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
847 EXPECT_CALL(*profile1.get(),
848 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
849 EXPECT_CALL(*profile1.get(),
850 AbandonService(IsRefPtrTo(s_configure_fail.get())))
851 .WillOnce(Return(true));
852 EXPECT_CALL(*profile1.get(),
853 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
854 .WillOnce(Return(true));
855
856 // Never allow services to re-join profile1.
857 EXPECT_CALL(*profile1.get(), ConfigureService(_))
858 .WillRepeatedly(Return(false));
859
860 // Only allow one of the members of the profile and group to successfully
861 // join profile0.
862 EXPECT_CALL(*profile0.get(),
863 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
864 EXPECT_CALL(*profile0.get(),
865 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
866 EXPECT_CALL(*profile0.get(),
867 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
868 .WillOnce(Return(false));
869 EXPECT_CALL(*profile0.get(),
870 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
871 .WillOnce(Return(true));
872
873 // Expect the failed-to-configure service to have Unload() called on it.
874 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
875 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
876 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
877 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
878
879 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
880
881 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
882 EXPECT_EQ(profile1, s_not_in_group->profile());
883 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
884
885 // Since we are using a MockProfile, the profile does not actually change,
886 // since ConfigureService was not actually called on the service.
887 EXPECT_EQ(profile1, s_configure_succeed->profile());
888}
889
Paul Stewart65512e12012-03-26 18:01:08 -0700890TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
891 MockServiceRefPtr s_will_remove0(
892 new NiceMock<MockService>(control_interface(),
893 dispatcher(),
894 metrics(),
895 manager()));
896 MockServiceRefPtr s_will_remove1(
897 new NiceMock<MockService>(control_interface(),
898 dispatcher(),
899 metrics(),
900 manager()));
901 MockServiceRefPtr s_will_not_remove0(
902 new NiceMock<MockService>(control_interface(),
903 dispatcher(),
904 metrics(),
905 manager()));
906 MockServiceRefPtr s_will_not_remove1(
907 new NiceMock<MockService>(control_interface(),
908 dispatcher(),
909 metrics(),
910 manager()));
911
912 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
913 .Times(4); // Once for each registration.
914
915 string entry_name("entry_name");
916 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
917 .WillRepeatedly(Return(entry_name));
918 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
919 .WillRepeatedly(Return(entry_name));
920 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
921 .WillRepeatedly(Return(entry_name));
922 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
923 .WillRepeatedly(Return(entry_name));
924
925 manager()->RegisterService(s_will_remove0);
926 manager()->RegisterService(s_will_not_remove0);
927 manager()->RegisterService(s_will_remove1);
928 manager()->RegisterService(s_will_not_remove1);
929
930 // One for each service added above.
931 ASSERT_EQ(4, manager()->services_.size());
932
933 scoped_refptr<MockProfile> profile(
934 new StrictMock<MockProfile>(control_interface(), manager(), ""));
935
936 s_will_remove0->set_profile(profile);
937 s_will_remove1->set_profile(profile);
938 s_will_not_remove0->set_profile(profile);
939 s_will_not_remove1->set_profile(profile);
940
941 AdoptProfile(manager(), profile);
942
943 // Deny any of the services re-entry to the profile.
944 EXPECT_CALL(*profile, ConfigureService(_))
945 .WillRepeatedly(Return(false));
946
947 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
948 .WillOnce(Return(true));
949 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
950 .WillOnce(Return(true));
951 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
952 .WillOnce(Return(true));
953 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
954 .WillOnce(Return(true));
955
956 EXPECT_CALL(*s_will_remove0, Unload())
957 .WillOnce(Return(true));
958 EXPECT_CALL(*s_will_remove1, Unload())
959 .WillOnce(Return(true));
960 EXPECT_CALL(*s_will_not_remove0, Unload())
961 .WillOnce(Return(false));
962 EXPECT_CALL(*s_will_not_remove1, Unload())
963 .WillOnce(Return(false));
964
965
966 // This will cause all the profiles to be unloaded.
967 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
968
969 // 2 of the 4 services added above should have been unregistered and
970 // removed, leaving 2.
971 EXPECT_EQ(2, manager()->services_.size());
972 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
973 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
974}
975
976TEST_F(ManagerTest, PopProfileWithUnload) {
977 MockServiceRefPtr s_will_remove0(
978 new NiceMock<MockService>(control_interface(),
979 dispatcher(),
980 metrics(),
981 manager()));
982 MockServiceRefPtr s_will_remove1(
983 new NiceMock<MockService>(control_interface(),
984 dispatcher(),
985 metrics(),
986 manager()));
987 MockServiceRefPtr s_will_not_remove0(
988 new NiceMock<MockService>(control_interface(),
989 dispatcher(),
990 metrics(),
991 manager()));
992 MockServiceRefPtr s_will_not_remove1(
993 new NiceMock<MockService>(control_interface(),
994 dispatcher(),
995 metrics(),
996 manager()));
997
998 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
999 .Times(5); // Once for each registration, and one after profile pop.
1000
1001 manager()->RegisterService(s_will_remove0);
1002 manager()->RegisterService(s_will_not_remove0);
1003 manager()->RegisterService(s_will_remove1);
1004 manager()->RegisterService(s_will_not_remove1);
1005
1006 // One for each service added above.
1007 ASSERT_EQ(4, manager()->services_.size());
1008
1009 scoped_refptr<MockProfile> profile0(
1010 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1011 scoped_refptr<MockProfile> profile1(
1012 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1013
1014 s_will_remove0->set_profile(profile1);
1015 s_will_remove1->set_profile(profile1);
1016 s_will_not_remove0->set_profile(profile1);
1017 s_will_not_remove1->set_profile(profile1);
1018
1019 AdoptProfile(manager(), profile0);
1020 AdoptProfile(manager(), profile1);
1021
1022 // Deny any of the services entry to profile0, so they will all be unloaded.
1023 EXPECT_CALL(*profile0, ConfigureService(_))
1024 .WillRepeatedly(Return(false));
1025
1026 EXPECT_CALL(*s_will_remove0, Unload())
1027 .WillOnce(Return(true));
1028 EXPECT_CALL(*s_will_remove1, Unload())
1029 .WillOnce(Return(true));
1030 EXPECT_CALL(*s_will_not_remove0, Unload())
1031 .WillOnce(Return(false));
1032 EXPECT_CALL(*s_will_not_remove1, Unload())
1033 .WillOnce(Return(false));
1034
1035 // This will pop profile1, which should cause all our profiles to unload.
1036 manager()->PopProfileInternal();
1037
1038 // 2 of the 4 services added above should have been unregistered and
1039 // removed, leaving 2.
1040 EXPECT_EQ(2, manager()->services_.size());
1041 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1042 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1043}
1044
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001045TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001046 {
1047 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001048 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1049 flimflam::kOfflineModeProperty,
1050 PropertyStoreTest::kBoolV,
1051 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001052 }
1053 {
1054 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001055 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1056 flimflam::kCountryProperty,
1057 PropertyStoreTest::kStringV,
1058 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001059 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001060 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001061 {
1062 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001063 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1064 flimflam::kCountryProperty,
1065 PropertyStoreTest::kBoolV,
1066 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001067 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001068 }
1069 {
1070 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001071 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1072 flimflam::kOfflineModeProperty,
1073 PropertyStoreTest::kStringV,
1074 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001075 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001076 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001077 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001078 {
1079 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001080 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001081 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001082 flimflam::kEnabledTechnologiesProperty,
1083 PropertyStoreTest::kStringsV,
1084 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001085 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001086 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001087}
1088
mukesh agrawal32399322011-09-01 10:53:43 -07001089TEST_F(ManagerTest, RequestScan) {
1090 {
1091 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001092 manager()->RegisterDevice(mock_devices_[0].get());
1093 manager()->RegisterDevice(mock_devices_[1].get());
1094 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001095 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001096 EXPECT_CALL(*mock_devices_[0], Scan(_));
1097 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001098 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001099 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001100 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001101 }
1102
1103 {
1104 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001105 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001106 EXPECT_EQ(Error::kInvalidArguments, error.type());
1107 }
1108}
1109
Darin Petkovb65c2452012-02-23 15:17:06 +01001110TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001111 KeyValueStore args;
1112 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001113 manager()->GetService(args, &e);
1114 EXPECT_EQ(Error::kInvalidArguments, e.type());
1115 EXPECT_EQ("must specify service type", e.message());
1116}
1117
1118TEST_F(ManagerTest, GetServiceUnknownType) {
1119 KeyValueStore args;
1120 Error e;
1121 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1122 manager()->GetService(args, &e);
1123 EXPECT_EQ(Error::kNotSupported, e.type());
1124 EXPECT_EQ("service type is unsupported", e.message());
1125}
1126
1127TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1128 KeyValueStore args;
1129 Error e;
1130 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1131 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001132 EXPECT_EQ(Error::kInvalidArguments, e.type());
1133 EXPECT_EQ("no wifi devices available", e.message());
1134}
1135
Darin Petkovb65c2452012-02-23 15:17:06 +01001136TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001137 KeyValueStore args;
1138 Error e;
1139 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001140 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001141 manager()->RegisterDevice(mock_wifi_);
1142 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1143 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001144 manager()->GetService(args, &e);
1145 EXPECT_TRUE(e.IsSuccess());
1146}
1147
Darin Petkov33af05c2012-02-28 10:10:30 +01001148TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1149 KeyValueStore args;
1150 Error e;
1151 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
1152 ServiceRefPtr service = manager()->GetService(args, &e);
1153 EXPECT_EQ(Error::kNotSupported, e.type());
1154 EXPECT_FALSE(service);
1155}
1156
Darin Petkovb65c2452012-02-23 15:17:06 +01001157TEST_F(ManagerTest, GetServiceVPN) {
1158 KeyValueStore args;
1159 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001160 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001161 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001162 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1163 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +01001164 ServiceRefPtr service = manager()->GetService(args, &e);
1165 EXPECT_TRUE(e.IsSuccess());
1166 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001167}
1168
Paul Stewart7f61e522012-03-22 11:13:45 -07001169TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1170 // Manager calls ActiveProfile() so we need at least one profile installed.
1171 scoped_refptr<MockProfile> profile(
1172 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1173 AdoptProfile(manager(), profile);
1174
1175 KeyValueStore args;
1176 args.SetString(flimflam::kProfileProperty, "xxx");
1177 Error error;
1178 manager()->ConfigureService(args, &error);
1179 EXPECT_EQ(Error::kInvalidArguments, error.type());
1180 EXPECT_EQ("Invalid profile name xxx", error.message());
1181}
1182
1183TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1184 // Manager calls ActiveProfile() so we need at least one profile installed.
1185 scoped_refptr<MockProfile> profile(
1186 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1187 AdoptProfile(manager(), profile);
1188
1189 KeyValueStore args;
1190 Error error;
1191 manager()->ConfigureService(args, &error);
1192 EXPECT_EQ(Error::kInvalidArguments, error.type());
1193 EXPECT_EQ("must specify service type", error.message());
1194}
1195
1196// A registered service in the ephemeral profile should be moved to the
1197// active profile as a part of configuration if no profile was explicitly
1198// specified.
1199TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1200 scoped_refptr<MockProfile> profile(
1201 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1202
1203 AdoptProfile(manager(), profile); // This is now the active profile.
1204
1205 const std::vector<uint8_t> ssid;
1206 scoped_refptr<MockWiFiService> service(
1207 new NiceMock<MockWiFiService>(control_interface(),
1208 dispatcher(),
1209 metrics(),
1210 manager(),
1211 mock_wifi_,
1212 ssid,
1213 "",
1214 "",
1215 false));
1216
1217 manager()->RegisterService(service);
1218 service->set_profile(GetEphemeralProfile(manager()));
1219
1220 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1221 // the same device as that used above causes a refcounting loop.
1222 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1223 dispatcher(),
1224 metrics(),
1225 manager(),
1226 "wifi1",
1227 "addr5",
1228 5));
1229 manager()->RegisterDevice(wifi);
1230 EXPECT_CALL(*wifi, GetService(_, _))
1231 .WillOnce(Return(service));
1232 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1233 .WillOnce(Return(true));
1234 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1235 .WillOnce(Return(true));
1236
1237 KeyValueStore args;
1238 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1239 Error error;
1240 manager()->ConfigureService(args, &error);
1241 EXPECT_TRUE(error.IsSuccess());
1242}
1243
1244// If were configure a service that was already registered and explicitly
1245// specify a profile, it should be moved from the profile it was previously
1246// in to the specified profile if one was requested.
1247TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1248 scoped_refptr<MockProfile> profile0(
1249 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1250 scoped_refptr<MockProfile> profile1(
1251 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1252
1253 const string kProfileName0 = "profile0";
1254 const string kProfileName1 = "profile1";
1255
1256 EXPECT_CALL(*profile0, GetRpcIdentifier())
1257 .WillRepeatedly(Return(kProfileName0));
1258 EXPECT_CALL(*profile1, GetRpcIdentifier())
1259 .WillRepeatedly(Return(kProfileName1));
1260
1261 AdoptProfile(manager(), profile0);
1262 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1263
1264 const std::vector<uint8_t> ssid;
1265 scoped_refptr<MockWiFiService> service(
1266 new NiceMock<MockWiFiService>(control_interface(),
1267 dispatcher(),
1268 metrics(),
1269 manager(),
1270 mock_wifi_,
1271 ssid,
1272 "",
1273 "",
1274 false));
1275
1276 manager()->RegisterService(service);
1277 service->set_profile(profile1);
1278
1279 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1280 // the same device as that used above causes a refcounting loop.
1281 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1282 dispatcher(),
1283 metrics(),
1284 manager(),
1285 "wifi1",
1286 "addr5",
1287 5));
1288 manager()->RegisterDevice(wifi);
1289 EXPECT_CALL(*wifi, GetService(_, _))
1290 .WillOnce(Return(service));
1291 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1292 .WillOnce(Return(true));
1293 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1294 .WillOnce(Return(true));
1295 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1296 .WillOnce(Return(true));
1297
1298 KeyValueStore args;
1299 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1300 args.SetString(flimflam::kProfileProperty, kProfileName0);
1301 Error error;
1302 manager()->ConfigureService(args, &error);
1303 EXPECT_TRUE(error.IsSuccess());
1304 service->set_profile(NULL); // Breaks refcounting loop.
1305}
1306
1307// An unregistered service should remain unregistered, but its contents should
1308// be saved to the specified profile nonetheless.
1309TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1310 scoped_refptr<MockProfile> profile0(
1311 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1312 scoped_refptr<MockProfile> profile1(
1313 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1314
1315 const string kProfileName0 = "profile0";
1316 const string kProfileName1 = "profile1";
1317
1318 EXPECT_CALL(*profile0, GetRpcIdentifier())
1319 .WillRepeatedly(Return(kProfileName0));
1320 EXPECT_CALL(*profile1, GetRpcIdentifier())
1321 .WillRepeatedly(Return(kProfileName1));
1322
1323 AdoptProfile(manager(), profile0);
1324 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1325
1326 const std::vector<uint8_t> ssid;
1327 scoped_refptr<MockWiFiService> service(
1328 new NiceMock<MockWiFiService>(control_interface(),
1329 dispatcher(),
1330 metrics(),
1331 manager(),
1332 mock_wifi_,
1333 ssid,
1334 "",
1335 "",
1336 false));
1337
1338 service->set_profile(profile1);
1339
1340 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1341 // the same device as that used above causes a refcounting loop.
1342 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1343 dispatcher(),
1344 metrics(),
1345 manager(),
1346 "wifi1",
1347 "addr5",
1348 5));
1349 manager()->RegisterDevice(wifi);
1350 EXPECT_CALL(*wifi, GetService(_, _))
1351 .WillOnce(Return(service));
1352 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1353 .WillOnce(Return(true));
1354 EXPECT_CALL(*profile0, AdoptService(_))
1355 .Times(0);
1356 EXPECT_CALL(*profile1, AdoptService(_))
1357 .Times(0);
1358
1359 KeyValueStore args;
1360 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1361 args.SetString(flimflam::kProfileProperty, kProfileName0);
1362 Error error;
1363 manager()->ConfigureService(args, &error);
1364 EXPECT_TRUE(error.IsSuccess());
1365}
1366
Paul Stewart22aa71b2011-09-16 12:15:11 -07001367TEST_F(ManagerTest, TechnologyOrder) {
1368 Error error;
1369 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1370 string(flimflam::kTypeWifi), &error);
1371 ASSERT_TRUE(error.IsSuccess());
1372 EXPECT_EQ(manager()->GetTechnologyOrder(),
1373 string(flimflam::kTypeEthernet) + "," +
1374 string(flimflam::kTypeWifi));
1375
1376 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1377 string(flimflam::kTypeWifi), &error);
1378 ASSERT_FALSE(error.IsSuccess());
1379 EXPECT_EQ(Error::kInvalidArguments, error.type());
1380 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1381 string(flimflam::kTypeWifi),
1382 manager()->GetTechnologyOrder());
1383}
1384
1385TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001386 // TODO(quiche): Some of these tests would probably fit better in
1387 // service_unittest, since the actual comparison of Services is
1388 // implemented in Service. (crosbug.com/23370)
1389
Paul Stewart22aa71b2011-09-16 12:15:11 -07001390 scoped_refptr<MockService> mock_service0(
1391 new NiceMock<MockService>(control_interface(),
1392 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001393 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001394 manager()));
1395 scoped_refptr<MockService> mock_service1(
1396 new NiceMock<MockService>(control_interface(),
1397 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001398 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001399 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001400
1401 manager()->RegisterService(mock_service0);
1402 manager()->RegisterService(mock_service1);
1403
1404 // Services should already be sorted by UniqueName
1405 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1406
1407 // Asking explictly to sort services should not change anything
1408 manager()->SortServices();
1409 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1410
1411 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001412 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001413 manager()->UpdateService(mock_service1);
1414 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1415
1416 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001417 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001418 manager()->UpdateService(mock_service0);
1419 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1420
1421 // Technology
1422 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1423 .WillRepeatedly(Return(true));
1424 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1425 .WillRepeatedly(Return(true));
1426 // NB: Redefine default (false) return values so we don't use the default rule
1427 // which makes the logs noisier
1428 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1429 .WillRepeatedly(Return(false));
1430 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1431 .WillRepeatedly(Return(false));
1432
1433 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001434 // Default technology ordering should favor Ethernet over WiFi.
1435 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001436 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1437
1438 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1439 string(flimflam::kTypeEthernet), &error);
1440 EXPECT_TRUE(error.IsSuccess());
1441 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1442
Gaurav Shah435de2c2011-11-17 19:01:07 -08001443 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001444 mock_service0->set_priority(1);
1445 manager()->UpdateService(mock_service0);
1446 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1447
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001448 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001449 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001450 manager()->UpdateService(mock_service1);
1451 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1452
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001453 // Auto-connect.
1454 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001455 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001456 mock_service1->set_auto_connect(false);
1457 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001458 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1459
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001460 // Connectable.
1461 mock_service1->set_connectable(true);
1462 manager()->UpdateService(mock_service1);
1463 mock_service0->set_connectable(false);
1464 manager()->UpdateService(mock_service0);
1465 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1466
1467 // IsFailed.
1468 EXPECT_CALL(*mock_service0.get(), state())
1469 .WillRepeatedly(Return(Service::kStateIdle));
1470 EXPECT_CALL(*mock_service0.get(), IsFailed())
1471 .WillRepeatedly(Return(false));
1472 manager()->UpdateService(mock_service0);
1473 EXPECT_CALL(*mock_service0.get(), state())
1474 .WillRepeatedly(Return(Service::kStateFailure));
1475 EXPECT_CALL(*mock_service1.get(), IsFailed())
1476 .WillRepeatedly(Return(true));
1477 manager()->UpdateService(mock_service1);
1478 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1479
1480 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001481 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001482 .WillRepeatedly(Return(Service::kStateAssociating));
1483 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001484 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001485 manager()->UpdateService(mock_service1);
1486 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1487
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001488 // Connected.
1489 EXPECT_CALL(*mock_service0.get(), state())
1490 .WillRepeatedly(Return(Service::kStateConnected));
1491 EXPECT_CALL(*mock_service0.get(), IsConnected())
1492 .WillRepeatedly(Return(true));
1493 manager()->UpdateService(mock_service0);
1494 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1495
Paul Stewart22aa71b2011-09-16 12:15:11 -07001496 manager()->DeregisterService(mock_service0);
1497 manager()->DeregisterService(mock_service1);
1498}
1499
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001500TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001501 MockMetrics mock_metrics;
1502 manager()->set_metrics(&mock_metrics);
1503
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001504 scoped_refptr<MockService> mock_service0(
1505 new NiceMock<MockService>(control_interface(),
1506 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001507 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001508 manager()));
1509 scoped_refptr<MockService> mock_service1(
1510 new NiceMock<MockService>(control_interface(),
1511 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001512 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001513 manager()));
1514
1515 scoped_refptr<MockConnection> mock_connection0(
1516 new NiceMock<MockConnection>(device_info_.get()));
1517 scoped_refptr<MockConnection> mock_connection1(
1518 new NiceMock<MockConnection>(device_info_.get()));
1519
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_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001522 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001523 manager()->RegisterService(mock_service1);
1524
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001525 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1526 manager()->SortServices();
1527
1528 mock_service1->set_priority(1);
1529 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1530 manager()->SortServices();
1531
1532 mock_service1->set_priority(0);
1533 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1534 manager()->SortServices();
1535
Paul Stewartce4ec192012-03-14 12:53:46 -07001536 mock_service0->set_mock_connection(mock_connection0);
1537 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001538
1539 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001540 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001541 manager()->SortServices();
1542
1543 mock_service1->set_priority(1);
1544 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1545 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001546 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001547 manager()->SortServices();
1548
1549 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001550 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001551 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001552 manager()->DeregisterService(mock_service1);
1553
Paul Stewartce4ec192012-03-14 12:53:46 -07001554 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001555 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001556 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001557
1558 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1559 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001560}
1561
Gaurav Shah435de2c2011-11-17 19:01:07 -08001562TEST_F(ManagerTest, AvailableTechnologies) {
1563 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1564 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001565 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001566 manager(),
1567 "null4",
1568 "addr4",
1569 0));
1570 manager()->RegisterDevice(mock_devices_[0]);
1571 manager()->RegisterDevice(mock_devices_[1]);
1572 manager()->RegisterDevice(mock_devices_[2]);
1573 manager()->RegisterDevice(mock_devices_[3]);
1574
1575 ON_CALL(*mock_devices_[0].get(), technology())
1576 .WillByDefault(Return(Technology::kEthernet));
1577 ON_CALL(*mock_devices_[1].get(), technology())
1578 .WillByDefault(Return(Technology::kWifi));
1579 ON_CALL(*mock_devices_[2].get(), technology())
1580 .WillByDefault(Return(Technology::kCellular));
1581 ON_CALL(*mock_devices_[3].get(), technology())
1582 .WillByDefault(Return(Technology::kWifi));
1583
1584 set<string> expected_technologies;
1585 expected_technologies.insert(Technology::NameFromIdentifier(
1586 Technology::kEthernet));
1587 expected_technologies.insert(Technology::NameFromIdentifier(
1588 Technology::kWifi));
1589 expected_technologies.insert(Technology::NameFromIdentifier(
1590 Technology::kCellular));
1591 Error error;
1592 vector<string> technologies = manager()->AvailableTechnologies(&error);
1593
1594 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1595 ContainerEq(expected_technologies));
1596}
1597
1598TEST_F(ManagerTest, ConnectedTechnologies) {
1599 scoped_refptr<MockService> connected_service1(
1600 new NiceMock<MockService>(control_interface(),
1601 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001602 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001603 manager()));
1604 scoped_refptr<MockService> connected_service2(
1605 new NiceMock<MockService>(control_interface(),
1606 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001607 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001608 manager()));
1609 scoped_refptr<MockService> disconnected_service1(
1610 new NiceMock<MockService>(control_interface(),
1611 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001612 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001613 manager()));
1614 scoped_refptr<MockService> disconnected_service2(
1615 new NiceMock<MockService>(control_interface(),
1616 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001617 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001618 manager()));
1619
1620 ON_CALL(*connected_service1.get(), IsConnected())
1621 .WillByDefault(Return(true));
1622 ON_CALL(*connected_service2.get(), IsConnected())
1623 .WillByDefault(Return(true));
1624
1625 manager()->RegisterService(connected_service1);
1626 manager()->RegisterService(connected_service2);
1627 manager()->RegisterService(disconnected_service1);
1628 manager()->RegisterService(disconnected_service2);
1629
1630 manager()->RegisterDevice(mock_devices_[0]);
1631 manager()->RegisterDevice(mock_devices_[1]);
1632 manager()->RegisterDevice(mock_devices_[2]);
1633 manager()->RegisterDevice(mock_devices_[3]);
1634
1635 ON_CALL(*mock_devices_[0].get(), technology())
1636 .WillByDefault(Return(Technology::kEthernet));
1637 ON_CALL(*mock_devices_[1].get(), technology())
1638 .WillByDefault(Return(Technology::kWifi));
1639 ON_CALL(*mock_devices_[2].get(), technology())
1640 .WillByDefault(Return(Technology::kCellular));
1641 ON_CALL(*mock_devices_[3].get(), technology())
1642 .WillByDefault(Return(Technology::kWifi));
1643
1644 mock_devices_[0]->SelectService(connected_service1);
1645 mock_devices_[1]->SelectService(disconnected_service1);
1646 mock_devices_[2]->SelectService(disconnected_service2);
1647 mock_devices_[3]->SelectService(connected_service2);
1648
1649 set<string> expected_technologies;
1650 expected_technologies.insert(Technology::NameFromIdentifier(
1651 Technology::kEthernet));
1652 expected_technologies.insert(Technology::NameFromIdentifier(
1653 Technology::kWifi));
1654 Error error;
1655
1656 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1657 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1658 ContainerEq(expected_technologies));
1659}
1660
1661TEST_F(ManagerTest, DefaultTechnology) {
1662 scoped_refptr<MockService> connected_service(
1663 new NiceMock<MockService>(control_interface(),
1664 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001665 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001666 manager()));
1667 scoped_refptr<MockService> disconnected_service(
1668 new NiceMock<MockService>(control_interface(),
1669 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001670 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001671 manager()));
1672
1673 // Connected. WiFi.
1674 ON_CALL(*connected_service.get(), IsConnected())
1675 .WillByDefault(Return(true));
1676 ON_CALL(*connected_service.get(), state())
1677 .WillByDefault(Return(Service::kStateConnected));
1678 ON_CALL(*connected_service.get(), technology())
1679 .WillByDefault(Return(Technology::kWifi));
1680
1681 // Disconnected. Ethernet.
1682 ON_CALL(*disconnected_service.get(), technology())
1683 .WillByDefault(Return(Technology::kEthernet));
1684
1685 manager()->RegisterService(disconnected_service);
1686 Error error;
1687 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1688
1689
1690 manager()->RegisterService(connected_service);
1691 // Connected service should be brought to the front now.
1692 string expected_technology =
1693 Technology::NameFromIdentifier(Technology::kWifi);
1694 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1695}
1696
Thieu Le1271d682011-11-02 22:48:19 +00001697TEST_F(ManagerTest, DisconnectServicesOnStop) {
1698 scoped_refptr<MockService> mock_service(
1699 new NiceMock<MockService>(control_interface(),
1700 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001701 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001702 manager()));
1703 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001704 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001705 manager()->Stop();
1706}
1707
mukesh agrawal00917ce2011-11-22 23:56:55 +00001708TEST_F(ManagerTest, UpdateServiceConnected) {
1709 scoped_refptr<MockService> mock_service(
1710 new NiceMock<MockService>(control_interface(),
1711 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001712 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001713 manager()));
1714 manager()->RegisterService(mock_service);
1715 EXPECT_FALSE(mock_service->favorite());
1716 EXPECT_FALSE(mock_service->auto_connect());
1717
Gaurav Shah435de2c2011-11-17 19:01:07 -08001718 EXPECT_CALL(*mock_service.get(), IsConnected())
1719 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001720 manager()->UpdateService(mock_service);
1721 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1722 // to mock out MakeFavorite. And mocking that out would break the
1723 // SortServices test. (crosbug.com/23370)
1724 EXPECT_TRUE(mock_service->favorite());
1725 EXPECT_TRUE(mock_service->auto_connect());
1726}
1727
Thieu Led4e9e552012-02-16 16:26:07 -08001728TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1729 // This tests the case where the user connects to a service that is
1730 // currently associated with a profile. We want to make sure that the
1731 // favorite flag is set and that the flag is saved to the current
1732 // profile.
1733 scoped_refptr<MockService> mock_service(
1734 new NiceMock<MockService>(control_interface(),
1735 dispatcher(),
1736 metrics(),
1737 manager()));
1738 manager()->RegisterService(mock_service);
1739 EXPECT_FALSE(mock_service->favorite());
1740 EXPECT_FALSE(mock_service->auto_connect());
1741
1742 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1743 mock_service->set_profile(profile);
1744
1745 EXPECT_CALL(*mock_service.get(), IsConnected())
1746 .WillRepeatedly(Return(true));
1747 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1748 manager()->UpdateService(mock_service);
1749 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1750 // to mock out MakeFavorite. And mocking that out would break the
1751 // SortServices test. (crosbug.com/23370)
1752 EXPECT_TRUE(mock_service->favorite());
1753 EXPECT_TRUE(mock_service->auto_connect());
1754}
1755
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001756TEST_F(ManagerTest, SaveSuccessfulService) {
1757 scoped_refptr<MockProfile> profile(
1758 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1759 AdoptProfile(manager(), profile);
1760 scoped_refptr<MockService> service(
1761 new NiceMock<MockService>(control_interface(),
1762 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001763 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001764 manager()));
1765
1766 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1767 ServiceRefPtr expect_service(service.get());
1768
1769 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1770 .WillOnce(Return(false));
1771 manager()->RegisterService(service);
1772
1773 EXPECT_CALL(*service.get(), state())
1774 .WillRepeatedly(Return(Service::kStateConnected));
1775 EXPECT_CALL(*service.get(), IsConnected())
1776 .WillRepeatedly(Return(true));
1777 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1778 .WillOnce(Return(true));
1779 manager()->UpdateService(service);
1780}
1781
Paul Stewart1b253142012-01-26 14:05:52 -08001782TEST_F(ManagerTest, EnumerateProfiles) {
1783 vector<string> profile_paths;
1784 for (size_t i = 0; i < 10; i++) {
1785 scoped_refptr<MockProfile> profile(
1786 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001787 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001788 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1789 .WillOnce(Return(profile_paths.back()));
1790 AdoptProfile(manager(), profile);
1791 }
1792
1793 Error error;
1794 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1795 EXPECT_TRUE(error.IsSuccess());
1796 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1797 for (size_t i = 0; i < profile_paths.size(); i++) {
1798 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1799 }
1800}
1801
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001802TEST_F(ManagerTest, AutoConnectOnRegister) {
1803 MockServiceRefPtr service = MakeAutoConnectableService();
1804 EXPECT_CALL(*service.get(), AutoConnect());
1805 manager()->RegisterService(service);
1806 dispatcher()->DispatchPendingEvents();
1807}
1808
1809TEST_F(ManagerTest, AutoConnectOnUpdate) {
1810 MockServiceRefPtr service1 = MakeAutoConnectableService();
1811 service1->set_priority(1);
1812 MockServiceRefPtr service2 = MakeAutoConnectableService();
1813 service2->set_priority(2);
1814 manager()->RegisterService(service1);
1815 manager()->RegisterService(service2);
1816 dispatcher()->DispatchPendingEvents();
1817
1818 EXPECT_CALL(*service1.get(), AutoConnect());
1819 EXPECT_CALL(*service2.get(), state())
1820 .WillRepeatedly(Return(Service::kStateFailure));
1821 EXPECT_CALL(*service2.get(), IsFailed())
1822 .WillRepeatedly(Return(true));
1823 EXPECT_CALL(*service2.get(), IsConnected())
1824 .WillRepeatedly(Return(false));
1825 manager()->UpdateService(service2);
1826 dispatcher()->DispatchPendingEvents();
1827}
1828
1829TEST_F(ManagerTest, AutoConnectOnDeregister) {
1830 MockServiceRefPtr service1 = MakeAutoConnectableService();
1831 service1->set_priority(1);
1832 MockServiceRefPtr service2 = MakeAutoConnectableService();
1833 service2->set_priority(2);
1834 manager()->RegisterService(service1);
1835 manager()->RegisterService(service2);
1836 dispatcher()->DispatchPendingEvents();
1837
1838 EXPECT_CALL(*service1.get(), AutoConnect());
1839 manager()->DeregisterService(service2);
1840 dispatcher()->DispatchPendingEvents();
1841}
1842
Paul Stewartc681fa02012-03-02 19:40:04 -08001843TEST_F(ManagerTest, RecheckPortal) {
1844 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1845 .WillOnce(Return(false));
1846 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1847 .WillOnce(Return(true));
1848 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1849 .Times(0);
1850
1851 manager()->RegisterDevice(mock_devices_[0]);
1852 manager()->RegisterDevice(mock_devices_[1]);
1853 manager()->RegisterDevice(mock_devices_[2]);
1854
1855 manager()->RecheckPortal(NULL);
1856}
1857
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001858TEST_F(ManagerTest, GetDefaultService) {
1859 EXPECT_FALSE(manager()->GetDefaultService().get());
1860
1861 scoped_refptr<MockService> mock_service(
1862 new NiceMock<MockService>(control_interface(),
1863 dispatcher(),
1864 metrics(),
1865 manager()));
1866
1867 manager()->RegisterService(mock_service);
1868 EXPECT_FALSE(manager()->GetDefaultService().get());
1869
1870 scoped_refptr<MockConnection> mock_connection(
1871 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001872 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001873 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1874
Paul Stewartce4ec192012-03-14 12:53:46 -07001875 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001876 manager()->DeregisterService(mock_service);
1877}
1878
Paul Stewart13ed2252012-03-21 12:52:46 -07001879TEST_F(ManagerTest, GetServiceWithGUID) {
1880 scoped_refptr<MockService> mock_service0(
1881 new NiceMock<MockService>(control_interface(),
1882 dispatcher(),
1883 metrics(),
1884 manager()));
1885
1886 scoped_refptr<MockService> mock_service1(
1887 new NiceMock<MockService>(control_interface(),
1888 dispatcher(),
1889 metrics(),
1890 manager()));
1891
Paul Stewartcb59fed2012-03-21 21:14:46 -07001892 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1893 .Times(0);
1894 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1895 .Times(0);
1896
Paul Stewart13ed2252012-03-21 12:52:46 -07001897 manager()->RegisterService(mock_service0);
1898 manager()->RegisterService(mock_service1);
1899
1900 const string kGUID0 = "GUID0";
1901 const string kGUID1 = "GUID1";
1902
1903 {
1904 Error error;
1905 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1906 EXPECT_FALSE(error.IsSuccess());
1907 EXPECT_FALSE(service);
1908 }
1909
1910 KeyValueStore args;
1911 args.SetString(flimflam::kGuidProperty, kGUID1);
1912
1913 {
1914 Error error;
1915 ServiceRefPtr service = manager()->GetService(args, &error);
1916 EXPECT_EQ(Error::kInvalidArguments, error.type());
1917 EXPECT_FALSE(service);
1918 }
1919
1920 mock_service0->set_guid(kGUID0);
1921 mock_service1->set_guid(kGUID1);
1922
1923 {
1924 Error error;
1925 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1926 EXPECT_TRUE(error.IsSuccess());
1927 EXPECT_EQ(mock_service0.get(), service.get());
1928 }
1929
1930 {
1931 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07001932 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
1933 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07001934 ServiceRefPtr service = manager()->GetService(args, &error);
1935 EXPECT_TRUE(error.IsSuccess());
1936 EXPECT_EQ(mock_service1.get(), service.get());
1937 }
1938
1939 manager()->DeregisterService(mock_service0);
1940 manager()->DeregisterService(mock_service1);
1941}
1942
Gary Morain028545d2012-04-07 14:55:52 -07001943
1944TEST_F(ManagerTest, CalculateStateOffline) {
1945 MockMetrics mock_metrics;
1946 manager()->set_metrics(&mock_metrics);
1947 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
1948 .Times(AnyNumber());
1949 scoped_refptr<MockService> mock_service0(
1950 new NiceMock<MockService>(control_interface(),
1951 dispatcher(),
1952 metrics(),
1953 manager()));
1954
1955 scoped_refptr<MockService> mock_service1(
1956 new NiceMock<MockService>(control_interface(),
1957 dispatcher(),
1958 metrics(),
1959 manager()));
1960
1961 EXPECT_CALL(*mock_service0.get(), IsConnected())
1962 .WillRepeatedly(Return(false));
1963 EXPECT_CALL(*mock_service1.get(), IsConnected())
1964 .WillRepeatedly(Return(false));
1965
1966 manager()->RegisterService(mock_service0);
1967 manager()->RegisterService(mock_service1);
1968
1969 EXPECT_EQ("offline", manager()->CalculateState(NULL));
1970
1971 manager()->DeregisterService(mock_service0);
1972 manager()->DeregisterService(mock_service1);
1973}
1974
1975TEST_F(ManagerTest, CalculateStateOnline) {
1976 MockMetrics mock_metrics;
1977 manager()->set_metrics(&mock_metrics);
1978 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
1979 .Times(AnyNumber());
1980 scoped_refptr<MockService> mock_service0(
1981 new NiceMock<MockService>(control_interface(),
1982 dispatcher(),
1983 metrics(),
1984 manager()));
1985
1986 scoped_refptr<MockService> mock_service1(
1987 new NiceMock<MockService>(control_interface(),
1988 dispatcher(),
1989 metrics(),
1990 manager()));
1991
1992 EXPECT_CALL(*mock_service0.get(), IsConnected())
1993 .WillRepeatedly(Return(false));
1994 EXPECT_CALL(*mock_service1.get(), IsConnected())
1995 .WillRepeatedly(Return(true));
1996 EXPECT_CALL(*mock_service0.get(), state())
1997 .WillRepeatedly(Return(Service::kStateIdle));
1998 EXPECT_CALL(*mock_service1.get(), state())
1999 .WillRepeatedly(Return(Service::kStateConnected));
2000
2001 manager()->RegisterService(mock_service0);
2002 manager()->RegisterService(mock_service1);
2003
2004 EXPECT_EQ("online", manager()->CalculateState(NULL));
2005
2006 manager()->DeregisterService(mock_service0);
2007 manager()->DeregisterService(mock_service1);
2008}
2009
Chris Masone9be4a9d2011-05-16 15:44:09 -07002010} // namespace shill