blob: ea1ea57fd6a43fdc5d98b6bdcd07396a8e8627da [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07004
5#include "shill/manager.h"
6
Jason Glasgowdf7c5532012-05-14 14:41:45 -04007#include <map>
Chris Masone6791a432011-07-12 13:23:19 -07008#include <set>
9
Chris Masone9be4a9d2011-05-16 15:44:09 -070010#include <glib.h>
11
Paul Stewarte73d05c2012-03-29 16:26:05 -070012#include <base/file_util.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070013#include <base/logging.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/scoped_temp_dir.h>
15#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070016#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070018#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070019#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070020
mukesh agrawal32399322011-09-01 10:53:43 -070021#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070022#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070023#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070024#include "shill/glib.h"
25#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070026#include "shill/key_value_store.h"
mukesh agrawal32399322011-09-01 10:53:43 -070027#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080028#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070029#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070030#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080031#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070032#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000033#include "shill/mock_metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070034#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070035#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070036#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070037#include "shill/mock_wifi.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070038#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070040#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070041#include "shill/wifi_service.h"
Darin Petkovc63dcf02012-05-24 11:51:43 +020042#include "shill/wimax_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070043
44using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070045using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070046using std::string;
47using std::vector;
48
Chris Masone9be4a9d2011-05-16 15:44:09 -070049namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070050using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070051using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080052using ::testing::ContainerEq;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070053using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070054using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070055using ::testing::NiceMock;
56using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070057using ::testing::ReturnRef;
Gaurav Shah435de2c2011-11-17 19:01:07 -080058using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080059using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070060using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070061
Chris Masone3bd3c8c2011-06-13 08:20:26 -070062class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070063 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070064 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070065 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070066 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080067 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070068 manager(),
69 "wifi0",
70 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080071 4)),
72 device_info_(new NiceMock<MockDeviceInfo>(
73 control_interface(),
74 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080075 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080076 reinterpret_cast<Manager*>(NULL))),
77 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070078 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
79 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080080 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070081 manager(),
82 "null0",
83 "addr0",
84 0));
85 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
86 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080087 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070088 manager(),
89 "null1",
90 "addr1",
91 1));
92 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
93 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080094 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070095 manager(),
96 "null2",
97 "addr2",
98 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080099 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
100 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800101 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800102 manager(),
103 "null3",
104 "addr3",
105 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700106 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800107
108 // Replace the manager's adaptor with a quieter one, and one
109 // we can do EXPECT*() against. Passes ownership.
110 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700111 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700112 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700113
Paul Stewartfdd16072011-09-16 12:41:35 -0700114 bool IsDeviceRegistered(const DeviceRefPtr &device,
115 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700116 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700117 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700118 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700119 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700120 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700121
Paul Stewarta849a3d2011-11-03 05:54:09 -0700122 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
123 manager->profiles_.push_back(profile);
124 }
125
Paul Stewart75225512012-01-26 22:51:33 -0800126 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
127 return manager->ephemeral_profile_;
128 }
129
Chris Masone6515aab2011-10-12 16:19:09 -0700130 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
131 Profile::Identifier id("rather", "irrelevant");
132 scoped_ptr<Profile> profile(new Profile(control_interface(),
133 manager,
134 id,
135 "",
136 false));
137 FilePath final_path(storage_path());
138 final_path = final_path.Append("test.profile");
139 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
140 storage->set_path(final_path);
141 if (!storage->Open())
142 return NULL;
143 profile->set_storage(storage.release()); // Passes ownership.
144 return profile.release();
145 }
146
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700147 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
148 const string &profile_identifier,
149 const string &service_name) {
150 GLib glib;
151 KeyFileStore store(&glib);
152 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
153 return store.Open() &&
154 store.SetString(service_name, "rather", "irrelevant") &&
155 store.Close();
156 }
157
158 Error::Type TestCreateProfile(Manager *manager, const string &name) {
159 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800160 string path;
161 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700162 return error.type();
163 }
164
165 Error::Type TestPopAnyProfile(Manager *manager) {
166 Error error;
167 manager->PopAnyProfile(&error);
168 return error.type();
169 }
170
171 Error::Type TestPopProfile(Manager *manager, const string &name) {
172 Error error;
173 manager->PopProfile(name, &error);
174 return error.type();
175 }
176
177 Error::Type TestPushProfile(Manager *manager, const string &name) {
178 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800179 string path;
180 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700181 return error.type();
182 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000183
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700184 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000185 typedef scoped_refptr<MockService> MockServiceRefPtr;
186
187 MockServiceRefPtr MakeAutoConnectableService() {
188 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
189 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800190 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000191 manager());
192 service->MakeFavorite();
193 service->set_connectable(true);
194 return service;
195 }
196
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700197 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700198 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800199 scoped_ptr<MockDeviceInfo> device_info_;
200
201 // This pointer is owned by the manager, and only tracked here for EXPECT*()
202 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700203};
204
Paul Stewart22aa71b2011-09-16 12:15:11 -0700205bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
206 return (svc0.get() == manager()->services_[0].get() &&
207 svc1.get() == manager()->services_[1].get());
208}
209
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700210TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700211 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
212 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700213}
214
Chris Masone9be4a9d2011-05-16 15:44:09 -0700215TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700216 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700217 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700218 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700219 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700220 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700221 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700222
Paul Stewart22aa71b2011-09-16 12:15:11 -0700223 manager()->RegisterDevice(mock_devices_[0]);
224 manager()->RegisterDevice(mock_devices_[1]);
225 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700226
Paul Stewart22aa71b2011-09-16 12:15:11 -0700227 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
228 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
229 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700230}
231
Paul Stewarta41e38d2011-11-11 07:47:29 -0800232TEST_F(ManagerTest, DeviceRegistrationAndStart) {
233 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500234 mock_devices_[0]->enabled_persistent_ = true;
235 mock_devices_[1]->enabled_persistent_ = false;
236 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800237 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500238 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800239 .Times(0);
240 manager()->RegisterDevice(mock_devices_[0]);
241 manager()->RegisterDevice(mock_devices_[1]);
242}
243
244TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
245 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
246 DeviceRefPtr device_ref(mock_devices_[0].get());
247 AdoptProfile(manager(), profile); // Passes ownership.
248 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
249 EXPECT_CALL(*profile, Save());
250 manager()->RegisterDevice(mock_devices_[0]);
251}
252
Chris Masone9be4a9d2011-05-16 15:44:09 -0700253TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700254 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700255 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700256 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700257 .WillByDefault(Return(true));
258
Gaurav Shah435de2c2011-11-17 19:01:07 -0800259 manager()->RegisterDevice(mock_devices_[0]);
260 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700261
Paul Stewart22aa71b2011-09-16 12:15:11 -0700262 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
263 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700264
Eric Shienbrood9a245532012-03-07 14:20:39 -0500265 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800266 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700267 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700268
Eric Shienbrood9a245532012-03-07 14:20:39 -0500269 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800270 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700271 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700272}
273
274TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700275 // It's much easier and safer to use a real GLib for this test.
276 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700277 Manager manager(control_interface(),
278 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800279 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700280 &glib,
281 run_path(),
282 storage_path(),
283 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700284 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
285 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700286 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700287
Chris Masone9be4a9d2011-05-16 15:44:09 -0700288 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700289 new NiceMock<MockService>(control_interface(),
290 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800291 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700292 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700293 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700294 new NiceMock<MockService>(control_interface(),
295 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800296 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700297 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700298
mukesh agrawal51a7e932011-07-27 16:18:26 -0700299 string service1_name(mock_service->UniqueName());
300 string service2_name(mock_service2->UniqueName());
301
302 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
303 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700304 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700305 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700306 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700307 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700308 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700309
Chris Masone9d779932011-08-25 16:33:41 -0700310 manager.RegisterService(mock_service);
311 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700312
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800313 Error error;
314 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700315 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700316 EXPECT_EQ(2, ids.size());
317 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
318 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700319
Chris Masone9d779932011-08-25 16:33:41 -0700320 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
321 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
322
323 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700324}
325
Chris Masone6515aab2011-10-12 16:19:09 -0700326TEST_F(ManagerTest, RegisterKnownService) {
327 // It's much easier and safer to use a real GLib for this test.
328 GLib glib;
329 Manager manager(control_interface(),
330 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800331 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700332 &glib,
333 run_path(),
334 storage_path(),
335 string());
336 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
337 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700338 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700339 {
340 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
341 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800342 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700343 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700344 ASSERT_TRUE(profile->AdoptService(service1));
345 ASSERT_TRUE(profile->ContainsService(service1));
346 } // Force destruction of service1.
347
348 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
349 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800350 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700351 &manager));
352 manager.RegisterService(service2);
353 EXPECT_EQ(service2->profile().get(), profile.get());
354 manager.Stop();
355}
356
357TEST_F(ManagerTest, RegisterUnknownService) {
358 // It's much easier and safer to use a real GLib for this test.
359 GLib glib;
360 Manager manager(control_interface(),
361 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800362 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700363 &glib,
364 run_path(),
365 storage_path(),
366 string());
367 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
368 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700369 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700370 {
371 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
372 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800373 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700374 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700375 ASSERT_TRUE(profile->AdoptService(service1));
376 ASSERT_TRUE(profile->ContainsService(service1));
377 } // Force destruction of service1.
378 scoped_refptr<MockService> mock_service2(
379 new NiceMock<MockService>(control_interface(),
380 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800381 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700382 &manager));
383 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
384 .WillRepeatedly(Return(mock_service2->UniqueName()));
385 manager.RegisterService(mock_service2);
386 EXPECT_NE(mock_service2->profile().get(), profile.get());
387 manager.Stop();
388}
389
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000390TEST_F(ManagerTest, DeregisterUnregisteredService) {
391 // WiFi assumes that it can deregister a service that is not
392 // registered. (E.g. a hidden service can be deregistered when it
393 // loses its last endpoint, and again when WiFi is Stop()-ed.)
394 //
395 // So test that doing so doesn't cause a crash.
396 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
397 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800398 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000399 manager());
400 manager()->DeregisterService(service);
401}
402
Chris Masonea8a2c252011-06-27 22:16:30 -0700403TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700404 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700405 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700406 map<string, ::DBus::Variant> props;
407 Error error(Error::kInvalidProperty, "");
408 {
409 ::DBus::Error dbus_error;
410 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700411 manager()->mutable_store()->SetStringProperty(
412 flimflam::kCheckPortalListProperty,
413 expected,
414 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700415 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700416 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
417 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
418 expected);
419 }
420 {
421 ::DBus::Error dbus_error;
422 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700423 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
424 expected,
425 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700426 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700427 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
428 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
429 expected);
430 }
431}
432
Chris Masone3c3f6a12011-07-01 10:01:41 -0700433TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700434 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700435 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800436 manager()->RegisterDevice(mock_devices_[0]);
437 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700438 {
439 map<string, ::DBus::Variant> props;
440 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700441 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700442 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
443 Strings devices =
444 props[flimflam::kDevicesProperty].operator vector<string>();
445 EXPECT_EQ(2, devices.size());
446 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700447}
448
mukesh agrawal2366eed2012-03-20 18:21:50 -0700449TEST_F(ManagerTest, GetServicesProperty) {
450 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
451 AdoptProfile(manager(), profile);
452 map<string, ::DBus::Variant> props;
453 ::DBus::Error dbus_error;
454 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
455 map<string, ::DBus::Variant>::const_iterator prop =
456 props.find(flimflam::kServicesProperty);
457 ASSERT_FALSE(prop == props.end());
458 const ::DBus::Variant &variant = prop->second;
459 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
460}
461
Chris Masone6791a432011-07-12 13:23:19 -0700462TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700463 Manager manager(control_interface(),
464 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800465 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700466 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700467 run_path(),
468 storage_path(),
469 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700470 scoped_refptr<MockService> s2(new MockService(control_interface(),
471 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800472 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700473 &manager));
474 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700475 {
Chris Masone6515aab2011-10-12 16:19:09 -0700476 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700477 ProfileRefPtr profile(
478 new Profile(control_interface(), &manager, id, "", false));
479 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700480 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700481 .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));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700490 EXPECT_TRUE(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
Gary Morainb672d352012-04-25 09:19:06 -0700586 // We should succeed in creating a valid user profile. Verify the returned
587 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700588 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700589 {
590 Error error;
591 string path;
592 manager.CreateProfile(kProfile, &path, &error);
593 EXPECT_EQ(Error::kSuccess, error.type());
594 EXPECT_EQ("/profile_rpc", path);
595 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700596
597 // We should fail in creating it a second time (already exists).
598 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
599}
600
601TEST_F(ManagerTest, PushPopProfile) {
602 // It's much easier to use real Glib in creating a Manager for this
603 // test here since we want the storage side-effects.
604 GLib glib;
605 ScopedTempDir temp_dir;
606 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
607 Manager manager(control_interface(),
608 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800609 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700610 &glib,
611 run_path(),
612 storage_path(),
613 temp_dir.path().value());
614
615 // Pushing an invalid profile should fail.
616 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
617
Paul Stewartd0a3b812012-03-28 22:48:22 -0700618 // Pushing a default profile that does not exist should fail.
619 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700620
621 const char kProfile0[] = "~user/profile0";
622 const char kProfile1[] = "~user/profile1";
623
624 // Create a couple of profiles.
625 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
626 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
627
628 // Push these profiles on the stack.
629 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
630 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
631
632 // Pushing a profile a second time should fail.
633 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
634 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
635
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800636 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700637 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800638 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700639
640 // Make sure a profile name that doesn't exist fails.
641 const char kProfile2Id[] = "profile2";
642 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
643 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
644
645 // Create a new service, with a specific storage name.
646 scoped_refptr<MockService> service(
647 new NiceMock<MockService>(control_interface(),
648 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800649 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700650 &manager));
651 const char kServiceName[] = "service_storage_name";
652 EXPECT_CALL(*service.get(), GetStorageIdentifier())
653 .WillRepeatedly(Return(kServiceName));
654 EXPECT_CALL(*service.get(), Load(_))
655 .WillRepeatedly(Return(true));
656
657 // Add this service to the manager -- it should end up in the ephemeral
658 // profile.
659 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800660 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700661
662 // Create storage for a profile that contains the service storage name.
663 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
664 kServiceName));
665
666 // When we push the profile, the service should move away from the
667 // ephemeral profile to this new profile since it has an entry for
668 // this service.
669 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800670 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700671 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
672
673 // Insert another profile that should supersede ownership of the service.
674 const char kProfile3Id[] = "profile3";
675 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
676 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
677 kServiceName));
678 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
679 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
680
681 // Popping an invalid profile name should fail.
682 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
683
684 // Popping an profile that is not at the top of the stack should fail.
685 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
686
687 // Popping the top profile should succeed.
688 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
689
690 // Moreover the service should have switched profiles to profile 2.
691 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
692
693 // Popping the top profile should succeed.
694 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
695
696 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800697 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700698
699 // Pop the remaining two services off the stack.
700 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
701 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
702
703 // Next pop should fail with "stack is empty".
704 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700705
706 const char kMachineProfile0[] = "machineprofile0";
707 const char kMachineProfile1[] = "machineprofile1";
708 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
709 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
710
711 // Should be able to push a machine profile.
712 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
713
714 // Should be able to push a user profile atop a machine profile.
715 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
716
717 // Pushing a system-wide profile on top of a user profile should fail.
718 EXPECT_EQ(Error::kInvalidArguments,
719 TestPushProfile(&manager, kMachineProfile1));
720
721 // However if we pop the user profile, we should be able stack another
722 // machine profile on.
723 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
724 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700725}
726
Paul Stewarte73d05c2012-03-29 16:26:05 -0700727TEST_F(ManagerTest, RemoveProfile) {
728 // It's much easier to use real Glib in creating a Manager for this
729 // test here since we want the storage side-effects.
730 GLib glib;
731 ScopedTempDir temp_dir;
732 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
733 Manager manager(control_interface(),
734 dispatcher(),
735 metrics(),
736 &glib,
737 run_path(),
738 storage_path(),
739 temp_dir.path().value());
740
741 const char kProfile0[] = "profile0";
742 FilePath profile_path(
743 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
744
745 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
746 ASSERT_TRUE(file_util::PathExists(profile_path));
747
748 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
749
750 // Remove should fail since the profile is still on the stack.
751 {
752 Error error;
753 manager.RemoveProfile(kProfile0, &error);
754 EXPECT_EQ(Error::kInvalidArguments, error.type());
755 }
756
757 // Profile path should still exist.
758 EXPECT_TRUE(file_util::PathExists(profile_path));
759
760 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
761
762 // This should succeed now that the profile is off the stack.
763 {
764 Error error;
765 manager.RemoveProfile(kProfile0, &error);
766 EXPECT_EQ(Error::kSuccess, error.type());
767 }
768
769 // Profile path should no longer exist.
770 EXPECT_FALSE(file_util::PathExists(profile_path));
771
772 // Another remove succeeds, due to a foible in file_util::Delete --
773 // it is not an error to delete a file that does not exist.
774 {
775 Error error;
776 manager.RemoveProfile(kProfile0, &error);
777 EXPECT_EQ(Error::kSuccess, error.type());
778 }
779
780 // Let's create an error case that will "work". Create a non-empty
781 // directory in the place of the profile pathname.
782 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
783 {
784 Error error;
785 manager.RemoveProfile(kProfile0, &error);
786 EXPECT_EQ(Error::kOperationFailed, error.type());
787 }
788}
789
Paul Stewart75225512012-01-26 22:51:33 -0800790// Use this matcher instead of passing RefPtrs directly into the arguments
791// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
792// system teardown.
793MATCHER_P(IsRefPtrTo, ref_address, "") {
794 return arg.get() == ref_address;
795}
796
797TEST_F(ManagerTest, HandleProfileEntryDeletion) {
798 MockServiceRefPtr s_not_in_profile(
799 new NiceMock<MockService>(control_interface(),
800 dispatcher(),
801 metrics(),
802 manager()));
803 MockServiceRefPtr s_not_in_group(
804 new NiceMock<MockService>(control_interface(),
805 dispatcher(),
806 metrics(),
807 manager()));
808 MockServiceRefPtr s_configure_fail(
809 new NiceMock<MockService>(control_interface(),
810 dispatcher(),
811 metrics(),
812 manager()));
813 MockServiceRefPtr s_configure_succeed(
814 new NiceMock<MockService>(control_interface(),
815 dispatcher(),
816 metrics(),
817 manager()));
818
819 string entry_name("entry_name");
820 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
821 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
822 .WillRepeatedly(Return("not_entry_name"));
823 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
824 .WillRepeatedly(Return(entry_name));
825 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
826 .WillRepeatedly(Return(entry_name));
827
828 manager()->RegisterService(s_not_in_profile);
829 manager()->RegisterService(s_not_in_group);
830 manager()->RegisterService(s_configure_fail);
831 manager()->RegisterService(s_configure_succeed);
832
833 scoped_refptr<MockProfile> profile0(
834 new StrictMock<MockProfile>(control_interface(), manager(), ""));
835 scoped_refptr<MockProfile> profile1(
836 new StrictMock<MockProfile>(control_interface(), manager(), ""));
837
838 s_not_in_group->set_profile(profile1);
839 s_configure_fail->set_profile(profile1);
840 s_configure_succeed->set_profile(profile1);
841
842 AdoptProfile(manager(), profile0);
843 AdoptProfile(manager(), profile1);
844
845 // No services are a member of this profile.
846 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
847
848 // No services that are members of this profile have this entry name.
849 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
850
851 // Only services that are members of the profile and group will be abandoned.
852 EXPECT_CALL(*profile1.get(),
853 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
854 EXPECT_CALL(*profile1.get(),
855 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
856 EXPECT_CALL(*profile1.get(),
857 AbandonService(IsRefPtrTo(s_configure_fail.get())))
858 .WillOnce(Return(true));
859 EXPECT_CALL(*profile1.get(),
860 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
861 .WillOnce(Return(true));
862
863 // Never allow services to re-join profile1.
864 EXPECT_CALL(*profile1.get(), ConfigureService(_))
865 .WillRepeatedly(Return(false));
866
867 // Only allow one of the members of the profile and group to successfully
868 // join profile0.
869 EXPECT_CALL(*profile0.get(),
870 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
871 EXPECT_CALL(*profile0.get(),
872 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
873 EXPECT_CALL(*profile0.get(),
874 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
875 .WillOnce(Return(false));
876 EXPECT_CALL(*profile0.get(),
877 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
878 .WillOnce(Return(true));
879
880 // Expect the failed-to-configure service to have Unload() called on it.
881 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
882 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
883 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
884 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
885
886 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
887
888 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
889 EXPECT_EQ(profile1, s_not_in_group->profile());
890 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
891
892 // Since we are using a MockProfile, the profile does not actually change,
893 // since ConfigureService was not actually called on the service.
894 EXPECT_EQ(profile1, s_configure_succeed->profile());
895}
896
Paul Stewart65512e12012-03-26 18:01:08 -0700897TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
898 MockServiceRefPtr s_will_remove0(
899 new NiceMock<MockService>(control_interface(),
900 dispatcher(),
901 metrics(),
902 manager()));
903 MockServiceRefPtr s_will_remove1(
904 new NiceMock<MockService>(control_interface(),
905 dispatcher(),
906 metrics(),
907 manager()));
908 MockServiceRefPtr s_will_not_remove0(
909 new NiceMock<MockService>(control_interface(),
910 dispatcher(),
911 metrics(),
912 manager()));
913 MockServiceRefPtr s_will_not_remove1(
914 new NiceMock<MockService>(control_interface(),
915 dispatcher(),
916 metrics(),
917 manager()));
918
919 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
920 .Times(4); // Once for each registration.
921
922 string entry_name("entry_name");
923 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
924 .WillRepeatedly(Return(entry_name));
925 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
926 .WillRepeatedly(Return(entry_name));
927 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
928 .WillRepeatedly(Return(entry_name));
929 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
930 .WillRepeatedly(Return(entry_name));
931
932 manager()->RegisterService(s_will_remove0);
933 manager()->RegisterService(s_will_not_remove0);
934 manager()->RegisterService(s_will_remove1);
935 manager()->RegisterService(s_will_not_remove1);
936
937 // One for each service added above.
938 ASSERT_EQ(4, manager()->services_.size());
939
940 scoped_refptr<MockProfile> profile(
941 new StrictMock<MockProfile>(control_interface(), manager(), ""));
942
943 s_will_remove0->set_profile(profile);
944 s_will_remove1->set_profile(profile);
945 s_will_not_remove0->set_profile(profile);
946 s_will_not_remove1->set_profile(profile);
947
948 AdoptProfile(manager(), profile);
949
950 // Deny any of the services re-entry to the profile.
951 EXPECT_CALL(*profile, ConfigureService(_))
952 .WillRepeatedly(Return(false));
953
954 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
955 .WillOnce(Return(true));
956 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
957 .WillOnce(Return(true));
958 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
959 .WillOnce(Return(true));
960 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
961 .WillOnce(Return(true));
962
963 EXPECT_CALL(*s_will_remove0, Unload())
964 .WillOnce(Return(true));
965 EXPECT_CALL(*s_will_remove1, Unload())
966 .WillOnce(Return(true));
967 EXPECT_CALL(*s_will_not_remove0, Unload())
968 .WillOnce(Return(false));
969 EXPECT_CALL(*s_will_not_remove1, Unload())
970 .WillOnce(Return(false));
971
972
973 // This will cause all the profiles to be unloaded.
974 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
975
976 // 2 of the 4 services added above should have been unregistered and
977 // removed, leaving 2.
978 EXPECT_EQ(2, manager()->services_.size());
979 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
980 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
981}
982
983TEST_F(ManagerTest, PopProfileWithUnload) {
984 MockServiceRefPtr s_will_remove0(
985 new NiceMock<MockService>(control_interface(),
986 dispatcher(),
987 metrics(),
988 manager()));
989 MockServiceRefPtr s_will_remove1(
990 new NiceMock<MockService>(control_interface(),
991 dispatcher(),
992 metrics(),
993 manager()));
994 MockServiceRefPtr s_will_not_remove0(
995 new NiceMock<MockService>(control_interface(),
996 dispatcher(),
997 metrics(),
998 manager()));
999 MockServiceRefPtr s_will_not_remove1(
1000 new NiceMock<MockService>(control_interface(),
1001 dispatcher(),
1002 metrics(),
1003 manager()));
1004
1005 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1006 .Times(5); // Once for each registration, and one after profile pop.
1007
1008 manager()->RegisterService(s_will_remove0);
1009 manager()->RegisterService(s_will_not_remove0);
1010 manager()->RegisterService(s_will_remove1);
1011 manager()->RegisterService(s_will_not_remove1);
1012
1013 // One for each service added above.
1014 ASSERT_EQ(4, manager()->services_.size());
1015
1016 scoped_refptr<MockProfile> profile0(
1017 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1018 scoped_refptr<MockProfile> profile1(
1019 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1020
1021 s_will_remove0->set_profile(profile1);
1022 s_will_remove1->set_profile(profile1);
1023 s_will_not_remove0->set_profile(profile1);
1024 s_will_not_remove1->set_profile(profile1);
1025
1026 AdoptProfile(manager(), profile0);
1027 AdoptProfile(manager(), profile1);
1028
1029 // Deny any of the services entry to profile0, so they will all be unloaded.
1030 EXPECT_CALL(*profile0, ConfigureService(_))
1031 .WillRepeatedly(Return(false));
1032
1033 EXPECT_CALL(*s_will_remove0, Unload())
1034 .WillOnce(Return(true));
1035 EXPECT_CALL(*s_will_remove1, Unload())
1036 .WillOnce(Return(true));
1037 EXPECT_CALL(*s_will_not_remove0, Unload())
1038 .WillOnce(Return(false));
1039 EXPECT_CALL(*s_will_not_remove1, Unload())
1040 .WillOnce(Return(false));
1041
1042 // This will pop profile1, which should cause all our profiles to unload.
1043 manager()->PopProfileInternal();
1044
1045 // 2 of the 4 services added above should have been unregistered and
1046 // removed, leaving 2.
1047 EXPECT_EQ(2, manager()->services_.size());
1048 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1049 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1050}
1051
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001052TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001053 {
1054 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001055 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1056 flimflam::kOfflineModeProperty,
1057 PropertyStoreTest::kBoolV,
1058 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001059 }
1060 {
1061 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001062 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1063 flimflam::kCountryProperty,
1064 PropertyStoreTest::kStringV,
1065 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001066 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001067 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001068 {
1069 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001070 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1071 flimflam::kCountryProperty,
1072 PropertyStoreTest::kBoolV,
1073 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001074 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001075 }
1076 {
1077 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001078 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1079 flimflam::kOfflineModeProperty,
1080 PropertyStoreTest::kStringV,
1081 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001082 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001083 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001084 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001085 {
1086 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001087 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001088 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001089 flimflam::kEnabledTechnologiesProperty,
1090 PropertyStoreTest::kStringsV,
1091 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001092 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001093 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001094}
1095
mukesh agrawal32399322011-09-01 10:53:43 -07001096TEST_F(ManagerTest, RequestScan) {
1097 {
1098 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001099 manager()->RegisterDevice(mock_devices_[0].get());
1100 manager()->RegisterDevice(mock_devices_[1].get());
1101 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001102 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001103 EXPECT_CALL(*mock_devices_[0], Scan(_));
1104 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001105 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001106 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001107 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001108 }
1109
1110 {
1111 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001112 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001113 EXPECT_EQ(Error::kInvalidArguments, error.type());
1114 }
1115}
1116
Darin Petkovb65c2452012-02-23 15:17:06 +01001117TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001118 KeyValueStore args;
1119 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001120 manager()->GetService(args, &e);
1121 EXPECT_EQ(Error::kInvalidArguments, e.type());
1122 EXPECT_EQ("must specify service type", e.message());
1123}
1124
1125TEST_F(ManagerTest, GetServiceUnknownType) {
1126 KeyValueStore args;
1127 Error e;
1128 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1129 manager()->GetService(args, &e);
1130 EXPECT_EQ(Error::kNotSupported, e.type());
1131 EXPECT_EQ("service type is unsupported", e.message());
1132}
1133
1134TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1135 KeyValueStore args;
1136 Error e;
1137 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1138 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001139 EXPECT_EQ(Error::kInvalidArguments, e.type());
1140 EXPECT_EQ("no wifi devices available", e.message());
1141}
1142
Darin Petkovb65c2452012-02-23 15:17:06 +01001143TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001144 KeyValueStore args;
1145 Error e;
1146 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001147 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001148 manager()->RegisterDevice(mock_wifi_);
1149 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1150 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001151 manager()->GetService(args, &e);
1152 EXPECT_TRUE(e.IsSuccess());
1153}
1154
Darin Petkov33af05c2012-02-28 10:10:30 +01001155TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1156 KeyValueStore args;
1157 Error e;
1158 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
1159 ServiceRefPtr service = manager()->GetService(args, &e);
1160 EXPECT_EQ(Error::kNotSupported, e.type());
1161 EXPECT_FALSE(service);
1162}
1163
Darin Petkovb65c2452012-02-23 15:17:06 +01001164TEST_F(ManagerTest, GetServiceVPN) {
1165 KeyValueStore args;
1166 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001167 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001168 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001169 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1170 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +01001171 ServiceRefPtr service = manager()->GetService(args, &e);
1172 EXPECT_TRUE(e.IsSuccess());
1173 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001174}
1175
Darin Petkovc63dcf02012-05-24 11:51:43 +02001176TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1177 KeyValueStore args;
1178 Error e;
1179 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1180 ServiceRefPtr service = manager()->GetService(args, &e);
1181 EXPECT_EQ(Error::kInvalidArguments, e.type());
1182 EXPECT_EQ("Missing WiMAX network id.", e.message());
1183 EXPECT_FALSE(service);
1184}
1185
Darin Petkovd1cd7972012-05-22 15:26:15 +02001186TEST_F(ManagerTest, GetServiceWiMax) {
1187 KeyValueStore args;
1188 Error e;
1189 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001190 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1191 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1192 ServiceRefPtr service = manager()->GetService(args, &e);
1193 EXPECT_TRUE(e.IsSuccess());
1194 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001195}
1196
Paul Stewart7f61e522012-03-22 11:13:45 -07001197TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1198 // Manager calls ActiveProfile() so we need at least one profile installed.
1199 scoped_refptr<MockProfile> profile(
1200 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1201 AdoptProfile(manager(), profile);
1202
1203 KeyValueStore args;
1204 args.SetString(flimflam::kProfileProperty, "xxx");
1205 Error error;
1206 manager()->ConfigureService(args, &error);
1207 EXPECT_EQ(Error::kInvalidArguments, error.type());
1208 EXPECT_EQ("Invalid profile name xxx", error.message());
1209}
1210
1211TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1212 // Manager calls ActiveProfile() so we need at least one profile installed.
1213 scoped_refptr<MockProfile> profile(
1214 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1215 AdoptProfile(manager(), profile);
1216
1217 KeyValueStore args;
1218 Error error;
1219 manager()->ConfigureService(args, &error);
1220 EXPECT_EQ(Error::kInvalidArguments, error.type());
1221 EXPECT_EQ("must specify service type", error.message());
1222}
1223
1224// A registered service in the ephemeral profile should be moved to the
1225// active profile as a part of configuration if no profile was explicitly
1226// specified.
1227TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1228 scoped_refptr<MockProfile> profile(
1229 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1230
1231 AdoptProfile(manager(), profile); // This is now the active profile.
1232
1233 const std::vector<uint8_t> ssid;
1234 scoped_refptr<MockWiFiService> service(
1235 new NiceMock<MockWiFiService>(control_interface(),
1236 dispatcher(),
1237 metrics(),
1238 manager(),
1239 mock_wifi_,
1240 ssid,
1241 "",
1242 "",
1243 false));
1244
1245 manager()->RegisterService(service);
1246 service->set_profile(GetEphemeralProfile(manager()));
1247
1248 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1249 // the same device as that used above causes a refcounting loop.
1250 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1251 dispatcher(),
1252 metrics(),
1253 manager(),
1254 "wifi1",
1255 "addr5",
1256 5));
1257 manager()->RegisterDevice(wifi);
1258 EXPECT_CALL(*wifi, GetService(_, _))
1259 .WillOnce(Return(service));
1260 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1261 .WillOnce(Return(true));
1262 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1263 .WillOnce(Return(true));
1264
1265 KeyValueStore args;
1266 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1267 Error error;
1268 manager()->ConfigureService(args, &error);
1269 EXPECT_TRUE(error.IsSuccess());
1270}
1271
1272// If were configure a service that was already registered and explicitly
1273// specify a profile, it should be moved from the profile it was previously
1274// in to the specified profile if one was requested.
1275TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1276 scoped_refptr<MockProfile> profile0(
1277 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1278 scoped_refptr<MockProfile> profile1(
1279 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1280
1281 const string kProfileName0 = "profile0";
1282 const string kProfileName1 = "profile1";
1283
1284 EXPECT_CALL(*profile0, GetRpcIdentifier())
1285 .WillRepeatedly(Return(kProfileName0));
1286 EXPECT_CALL(*profile1, GetRpcIdentifier())
1287 .WillRepeatedly(Return(kProfileName1));
1288
1289 AdoptProfile(manager(), profile0);
1290 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1291
1292 const std::vector<uint8_t> ssid;
1293 scoped_refptr<MockWiFiService> service(
1294 new NiceMock<MockWiFiService>(control_interface(),
1295 dispatcher(),
1296 metrics(),
1297 manager(),
1298 mock_wifi_,
1299 ssid,
1300 "",
1301 "",
1302 false));
1303
1304 manager()->RegisterService(service);
1305 service->set_profile(profile1);
1306
1307 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1308 // the same device as that used above causes a refcounting loop.
1309 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1310 dispatcher(),
1311 metrics(),
1312 manager(),
1313 "wifi1",
1314 "addr5",
1315 5));
1316 manager()->RegisterDevice(wifi);
1317 EXPECT_CALL(*wifi, GetService(_, _))
1318 .WillOnce(Return(service));
1319 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1320 .WillOnce(Return(true));
1321 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1322 .WillOnce(Return(true));
1323 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1324 .WillOnce(Return(true));
1325
1326 KeyValueStore args;
1327 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1328 args.SetString(flimflam::kProfileProperty, kProfileName0);
1329 Error error;
1330 manager()->ConfigureService(args, &error);
1331 EXPECT_TRUE(error.IsSuccess());
1332 service->set_profile(NULL); // Breaks refcounting loop.
1333}
1334
1335// An unregistered service should remain unregistered, but its contents should
1336// be saved to the specified profile nonetheless.
1337TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1338 scoped_refptr<MockProfile> profile0(
1339 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1340 scoped_refptr<MockProfile> profile1(
1341 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1342
1343 const string kProfileName0 = "profile0";
1344 const string kProfileName1 = "profile1";
1345
1346 EXPECT_CALL(*profile0, GetRpcIdentifier())
1347 .WillRepeatedly(Return(kProfileName0));
1348 EXPECT_CALL(*profile1, GetRpcIdentifier())
1349 .WillRepeatedly(Return(kProfileName1));
1350
1351 AdoptProfile(manager(), profile0);
1352 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1353
1354 const std::vector<uint8_t> ssid;
1355 scoped_refptr<MockWiFiService> service(
1356 new NiceMock<MockWiFiService>(control_interface(),
1357 dispatcher(),
1358 metrics(),
1359 manager(),
1360 mock_wifi_,
1361 ssid,
1362 "",
1363 "",
1364 false));
1365
1366 service->set_profile(profile1);
1367
1368 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1369 // the same device as that used above causes a refcounting loop.
1370 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1371 dispatcher(),
1372 metrics(),
1373 manager(),
1374 "wifi1",
1375 "addr5",
1376 5));
1377 manager()->RegisterDevice(wifi);
1378 EXPECT_CALL(*wifi, GetService(_, _))
1379 .WillOnce(Return(service));
1380 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1381 .WillOnce(Return(true));
1382 EXPECT_CALL(*profile0, AdoptService(_))
1383 .Times(0);
1384 EXPECT_CALL(*profile1, AdoptService(_))
1385 .Times(0);
1386
1387 KeyValueStore args;
1388 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1389 args.SetString(flimflam::kProfileProperty, kProfileName0);
1390 Error error;
1391 manager()->ConfigureService(args, &error);
1392 EXPECT_TRUE(error.IsSuccess());
1393}
1394
Paul Stewart22aa71b2011-09-16 12:15:11 -07001395TEST_F(ManagerTest, TechnologyOrder) {
1396 Error error;
1397 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1398 string(flimflam::kTypeWifi), &error);
1399 ASSERT_TRUE(error.IsSuccess());
1400 EXPECT_EQ(manager()->GetTechnologyOrder(),
1401 string(flimflam::kTypeEthernet) + "," +
1402 string(flimflam::kTypeWifi));
1403
1404 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1405 string(flimflam::kTypeWifi), &error);
1406 ASSERT_FALSE(error.IsSuccess());
1407 EXPECT_EQ(Error::kInvalidArguments, error.type());
1408 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1409 string(flimflam::kTypeWifi),
1410 manager()->GetTechnologyOrder());
1411}
1412
1413TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001414 // TODO(quiche): Some of these tests would probably fit better in
1415 // service_unittest, since the actual comparison of Services is
1416 // implemented in Service. (crosbug.com/23370)
1417
Paul Stewart22aa71b2011-09-16 12:15:11 -07001418 scoped_refptr<MockService> mock_service0(
1419 new NiceMock<MockService>(control_interface(),
1420 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001421 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001422 manager()));
1423 scoped_refptr<MockService> mock_service1(
1424 new NiceMock<MockService>(control_interface(),
1425 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001426 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001427 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001428
1429 manager()->RegisterService(mock_service0);
1430 manager()->RegisterService(mock_service1);
1431
1432 // Services should already be sorted by UniqueName
1433 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1434
1435 // Asking explictly to sort services should not change anything
1436 manager()->SortServices();
1437 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1438
1439 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001440 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001441 manager()->UpdateService(mock_service1);
1442 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1443
1444 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001445 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001446 manager()->UpdateService(mock_service0);
1447 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1448
1449 // Technology
1450 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1451 .WillRepeatedly(Return(true));
1452 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1453 .WillRepeatedly(Return(true));
1454 // NB: Redefine default (false) return values so we don't use the default rule
1455 // which makes the logs noisier
1456 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1457 .WillRepeatedly(Return(false));
1458 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1459 .WillRepeatedly(Return(false));
1460
1461 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001462 // Default technology ordering should favor Ethernet over WiFi.
1463 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001464 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1465
1466 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1467 string(flimflam::kTypeEthernet), &error);
1468 EXPECT_TRUE(error.IsSuccess());
1469 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1470
Gaurav Shah435de2c2011-11-17 19:01:07 -08001471 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001472 mock_service0->set_priority(1);
1473 manager()->UpdateService(mock_service0);
1474 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1475
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001476 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001477 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001478 manager()->UpdateService(mock_service1);
1479 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1480
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001481 // Auto-connect.
1482 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001483 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001484 mock_service1->set_auto_connect(false);
1485 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001486 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1487
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001488 // Connectable.
1489 mock_service1->set_connectable(true);
1490 manager()->UpdateService(mock_service1);
1491 mock_service0->set_connectable(false);
1492 manager()->UpdateService(mock_service0);
1493 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1494
1495 // IsFailed.
1496 EXPECT_CALL(*mock_service0.get(), state())
1497 .WillRepeatedly(Return(Service::kStateIdle));
1498 EXPECT_CALL(*mock_service0.get(), IsFailed())
1499 .WillRepeatedly(Return(false));
1500 manager()->UpdateService(mock_service0);
1501 EXPECT_CALL(*mock_service0.get(), state())
1502 .WillRepeatedly(Return(Service::kStateFailure));
1503 EXPECT_CALL(*mock_service1.get(), IsFailed())
1504 .WillRepeatedly(Return(true));
1505 manager()->UpdateService(mock_service1);
1506 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1507
1508 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001509 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001510 .WillRepeatedly(Return(Service::kStateAssociating));
1511 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001512 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001513 manager()->UpdateService(mock_service1);
1514 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1515
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001516 // Connected.
1517 EXPECT_CALL(*mock_service0.get(), state())
1518 .WillRepeatedly(Return(Service::kStateConnected));
1519 EXPECT_CALL(*mock_service0.get(), IsConnected())
1520 .WillRepeatedly(Return(true));
1521 manager()->UpdateService(mock_service0);
1522 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1523
Paul Stewart22aa71b2011-09-16 12:15:11 -07001524 manager()->DeregisterService(mock_service0);
1525 manager()->DeregisterService(mock_service1);
1526}
1527
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001528TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001529 MockMetrics mock_metrics;
1530 manager()->set_metrics(&mock_metrics);
1531
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001532 scoped_refptr<MockService> mock_service0(
1533 new NiceMock<MockService>(control_interface(),
1534 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001535 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001536 manager()));
1537 scoped_refptr<MockService> mock_service1(
1538 new NiceMock<MockService>(control_interface(),
1539 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001540 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001541 manager()));
1542
1543 scoped_refptr<MockConnection> mock_connection0(
1544 new NiceMock<MockConnection>(device_info_.get()));
1545 scoped_refptr<MockConnection> mock_connection1(
1546 new NiceMock<MockConnection>(device_info_.get()));
1547
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001548 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001549 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001550 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001551 manager()->RegisterService(mock_service1);
1552
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001553 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1554 manager()->SortServices();
1555
1556 mock_service1->set_priority(1);
1557 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1558 manager()->SortServices();
1559
1560 mock_service1->set_priority(0);
1561 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1562 manager()->SortServices();
1563
Paul Stewartce4ec192012-03-14 12:53:46 -07001564 mock_service0->set_mock_connection(mock_connection0);
1565 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001566
1567 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001568 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001569 manager()->SortServices();
1570
1571 mock_service1->set_priority(1);
1572 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1573 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001574 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001575 manager()->SortServices();
1576
1577 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001578 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001579 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001580 manager()->DeregisterService(mock_service1);
1581
Paul Stewartce4ec192012-03-14 12:53:46 -07001582 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001583 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001584 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001585
1586 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1587 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001588}
1589
Gaurav Shah435de2c2011-11-17 19:01:07 -08001590TEST_F(ManagerTest, AvailableTechnologies) {
1591 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1592 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001593 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001594 manager(),
1595 "null4",
1596 "addr4",
1597 0));
1598 manager()->RegisterDevice(mock_devices_[0]);
1599 manager()->RegisterDevice(mock_devices_[1]);
1600 manager()->RegisterDevice(mock_devices_[2]);
1601 manager()->RegisterDevice(mock_devices_[3]);
1602
1603 ON_CALL(*mock_devices_[0].get(), technology())
1604 .WillByDefault(Return(Technology::kEthernet));
1605 ON_CALL(*mock_devices_[1].get(), technology())
1606 .WillByDefault(Return(Technology::kWifi));
1607 ON_CALL(*mock_devices_[2].get(), technology())
1608 .WillByDefault(Return(Technology::kCellular));
1609 ON_CALL(*mock_devices_[3].get(), technology())
1610 .WillByDefault(Return(Technology::kWifi));
1611
1612 set<string> expected_technologies;
1613 expected_technologies.insert(Technology::NameFromIdentifier(
1614 Technology::kEthernet));
1615 expected_technologies.insert(Technology::NameFromIdentifier(
1616 Technology::kWifi));
1617 expected_technologies.insert(Technology::NameFromIdentifier(
1618 Technology::kCellular));
1619 Error error;
1620 vector<string> technologies = manager()->AvailableTechnologies(&error);
1621
1622 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1623 ContainerEq(expected_technologies));
1624}
1625
1626TEST_F(ManagerTest, ConnectedTechnologies) {
1627 scoped_refptr<MockService> connected_service1(
1628 new NiceMock<MockService>(control_interface(),
1629 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001630 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001631 manager()));
1632 scoped_refptr<MockService> connected_service2(
1633 new NiceMock<MockService>(control_interface(),
1634 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001635 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001636 manager()));
1637 scoped_refptr<MockService> disconnected_service1(
1638 new NiceMock<MockService>(control_interface(),
1639 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001640 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001641 manager()));
1642 scoped_refptr<MockService> disconnected_service2(
1643 new NiceMock<MockService>(control_interface(),
1644 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001645 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001646 manager()));
1647
1648 ON_CALL(*connected_service1.get(), IsConnected())
1649 .WillByDefault(Return(true));
1650 ON_CALL(*connected_service2.get(), IsConnected())
1651 .WillByDefault(Return(true));
1652
1653 manager()->RegisterService(connected_service1);
1654 manager()->RegisterService(connected_service2);
1655 manager()->RegisterService(disconnected_service1);
1656 manager()->RegisterService(disconnected_service2);
1657
1658 manager()->RegisterDevice(mock_devices_[0]);
1659 manager()->RegisterDevice(mock_devices_[1]);
1660 manager()->RegisterDevice(mock_devices_[2]);
1661 manager()->RegisterDevice(mock_devices_[3]);
1662
1663 ON_CALL(*mock_devices_[0].get(), technology())
1664 .WillByDefault(Return(Technology::kEthernet));
1665 ON_CALL(*mock_devices_[1].get(), technology())
1666 .WillByDefault(Return(Technology::kWifi));
1667 ON_CALL(*mock_devices_[2].get(), technology())
1668 .WillByDefault(Return(Technology::kCellular));
1669 ON_CALL(*mock_devices_[3].get(), technology())
1670 .WillByDefault(Return(Technology::kWifi));
1671
1672 mock_devices_[0]->SelectService(connected_service1);
1673 mock_devices_[1]->SelectService(disconnected_service1);
1674 mock_devices_[2]->SelectService(disconnected_service2);
1675 mock_devices_[3]->SelectService(connected_service2);
1676
1677 set<string> expected_technologies;
1678 expected_technologies.insert(Technology::NameFromIdentifier(
1679 Technology::kEthernet));
1680 expected_technologies.insert(Technology::NameFromIdentifier(
1681 Technology::kWifi));
1682 Error error;
1683
1684 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1685 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1686 ContainerEq(expected_technologies));
1687}
1688
1689TEST_F(ManagerTest, DefaultTechnology) {
1690 scoped_refptr<MockService> connected_service(
1691 new NiceMock<MockService>(control_interface(),
1692 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001693 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001694 manager()));
1695 scoped_refptr<MockService> disconnected_service(
1696 new NiceMock<MockService>(control_interface(),
1697 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001698 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001699 manager()));
1700
1701 // Connected. WiFi.
1702 ON_CALL(*connected_service.get(), IsConnected())
1703 .WillByDefault(Return(true));
1704 ON_CALL(*connected_service.get(), state())
1705 .WillByDefault(Return(Service::kStateConnected));
1706 ON_CALL(*connected_service.get(), technology())
1707 .WillByDefault(Return(Technology::kWifi));
1708
1709 // Disconnected. Ethernet.
1710 ON_CALL(*disconnected_service.get(), technology())
1711 .WillByDefault(Return(Technology::kEthernet));
1712
1713 manager()->RegisterService(disconnected_service);
1714 Error error;
1715 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1716
1717
1718 manager()->RegisterService(connected_service);
1719 // Connected service should be brought to the front now.
1720 string expected_technology =
1721 Technology::NameFromIdentifier(Technology::kWifi);
1722 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1723}
1724
Thieu Le1271d682011-11-02 22:48:19 +00001725TEST_F(ManagerTest, DisconnectServicesOnStop) {
1726 scoped_refptr<MockService> mock_service(
1727 new NiceMock<MockService>(control_interface(),
1728 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001729 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001730 manager()));
1731 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001732 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001733 manager()->Stop();
1734}
1735
mukesh agrawal00917ce2011-11-22 23:56:55 +00001736TEST_F(ManagerTest, UpdateServiceConnected) {
1737 scoped_refptr<MockService> mock_service(
1738 new NiceMock<MockService>(control_interface(),
1739 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001740 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001741 manager()));
1742 manager()->RegisterService(mock_service);
1743 EXPECT_FALSE(mock_service->favorite());
1744 EXPECT_FALSE(mock_service->auto_connect());
1745
Gaurav Shah435de2c2011-11-17 19:01:07 -08001746 EXPECT_CALL(*mock_service.get(), IsConnected())
1747 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001748 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
Thieu Led4e9e552012-02-16 16:26:07 -08001756TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1757 // This tests the case where the user connects to a service that is
1758 // currently associated with a profile. We want to make sure that the
1759 // favorite flag is set and that the flag is saved to the current
1760 // profile.
1761 scoped_refptr<MockService> mock_service(
1762 new NiceMock<MockService>(control_interface(),
1763 dispatcher(),
1764 metrics(),
1765 manager()));
1766 manager()->RegisterService(mock_service);
1767 EXPECT_FALSE(mock_service->favorite());
1768 EXPECT_FALSE(mock_service->auto_connect());
1769
Gary Moraind93615e2012-04-27 11:50:03 -07001770 scoped_refptr<MockProfile> profile(
1771 new MockProfile(control_interface(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08001772
Gary Moraind93615e2012-04-27 11:50:03 -07001773 mock_service->set_profile(profile);
1774 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08001775 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07001776 EXPECT_CALL(*profile,
1777 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08001778 manager()->UpdateService(mock_service);
1779 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1780 // to mock out MakeFavorite. And mocking that out would break the
1781 // SortServices test. (crosbug.com/23370)
1782 EXPECT_TRUE(mock_service->favorite());
1783 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07001784 // This releases the ref on the mock profile.
1785 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08001786}
1787
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001788TEST_F(ManagerTest, SaveSuccessfulService) {
1789 scoped_refptr<MockProfile> profile(
1790 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1791 AdoptProfile(manager(), profile);
1792 scoped_refptr<MockService> service(
1793 new NiceMock<MockService>(control_interface(),
1794 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001795 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001796 manager()));
1797
1798 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1799 ServiceRefPtr expect_service(service.get());
1800
1801 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1802 .WillOnce(Return(false));
1803 manager()->RegisterService(service);
1804
1805 EXPECT_CALL(*service.get(), state())
1806 .WillRepeatedly(Return(Service::kStateConnected));
1807 EXPECT_CALL(*service.get(), IsConnected())
1808 .WillRepeatedly(Return(true));
1809 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1810 .WillOnce(Return(true));
1811 manager()->UpdateService(service);
1812}
1813
Paul Stewart1b253142012-01-26 14:05:52 -08001814TEST_F(ManagerTest, EnumerateProfiles) {
1815 vector<string> profile_paths;
1816 for (size_t i = 0; i < 10; i++) {
1817 scoped_refptr<MockProfile> profile(
1818 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001819 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001820 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1821 .WillOnce(Return(profile_paths.back()));
1822 AdoptProfile(manager(), profile);
1823 }
1824
1825 Error error;
1826 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1827 EXPECT_TRUE(error.IsSuccess());
1828 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1829 for (size_t i = 0; i < profile_paths.size(); i++) {
1830 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1831 }
1832}
1833
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001834TEST_F(ManagerTest, AutoConnectOnRegister) {
1835 MockServiceRefPtr service = MakeAutoConnectableService();
1836 EXPECT_CALL(*service.get(), AutoConnect());
1837 manager()->RegisterService(service);
1838 dispatcher()->DispatchPendingEvents();
1839}
1840
1841TEST_F(ManagerTest, AutoConnectOnUpdate) {
1842 MockServiceRefPtr service1 = MakeAutoConnectableService();
1843 service1->set_priority(1);
1844 MockServiceRefPtr service2 = MakeAutoConnectableService();
1845 service2->set_priority(2);
1846 manager()->RegisterService(service1);
1847 manager()->RegisterService(service2);
1848 dispatcher()->DispatchPendingEvents();
1849
1850 EXPECT_CALL(*service1.get(), AutoConnect());
1851 EXPECT_CALL(*service2.get(), state())
1852 .WillRepeatedly(Return(Service::kStateFailure));
1853 EXPECT_CALL(*service2.get(), IsFailed())
1854 .WillRepeatedly(Return(true));
1855 EXPECT_CALL(*service2.get(), IsConnected())
1856 .WillRepeatedly(Return(false));
1857 manager()->UpdateService(service2);
1858 dispatcher()->DispatchPendingEvents();
1859}
1860
1861TEST_F(ManagerTest, AutoConnectOnDeregister) {
1862 MockServiceRefPtr service1 = MakeAutoConnectableService();
1863 service1->set_priority(1);
1864 MockServiceRefPtr service2 = MakeAutoConnectableService();
1865 service2->set_priority(2);
1866 manager()->RegisterService(service1);
1867 manager()->RegisterService(service2);
1868 dispatcher()->DispatchPendingEvents();
1869
1870 EXPECT_CALL(*service1.get(), AutoConnect());
1871 manager()->DeregisterService(service2);
1872 dispatcher()->DispatchPendingEvents();
1873}
1874
Paul Stewartc681fa02012-03-02 19:40:04 -08001875TEST_F(ManagerTest, RecheckPortal) {
1876 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1877 .WillOnce(Return(false));
1878 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1879 .WillOnce(Return(true));
1880 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1881 .Times(0);
1882
1883 manager()->RegisterDevice(mock_devices_[0]);
1884 manager()->RegisterDevice(mock_devices_[1]);
1885 manager()->RegisterDevice(mock_devices_[2]);
1886
1887 manager()->RecheckPortal(NULL);
1888}
1889
Paul Stewartd215af62012-04-24 23:25:50 -07001890TEST_F(ManagerTest, RecheckPortalOnService) {
1891 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1892 dispatcher(),
1893 metrics(),
1894 manager());
1895 EXPECT_CALL(*mock_devices_[0].get(),
1896 IsConnectedToService(IsRefPtrTo(service)))
1897 .WillOnce(Return(false));
1898 EXPECT_CALL(*mock_devices_[1].get(),
1899 IsConnectedToService(IsRefPtrTo(service)))
1900 .WillOnce(Return(true));
1901 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
1902 .WillOnce(Return(true));
1903 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
1904 .Times(0);
1905
1906 manager()->RegisterDevice(mock_devices_[0]);
1907 manager()->RegisterDevice(mock_devices_[1]);
1908 manager()->RegisterDevice(mock_devices_[2]);
1909
1910 manager()->RecheckPortalOnService(service);
1911}
1912
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001913TEST_F(ManagerTest, GetDefaultService) {
1914 EXPECT_FALSE(manager()->GetDefaultService().get());
1915
1916 scoped_refptr<MockService> mock_service(
1917 new NiceMock<MockService>(control_interface(),
1918 dispatcher(),
1919 metrics(),
1920 manager()));
1921
1922 manager()->RegisterService(mock_service);
1923 EXPECT_FALSE(manager()->GetDefaultService().get());
1924
1925 scoped_refptr<MockConnection> mock_connection(
1926 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001927 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001928 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1929
Paul Stewartce4ec192012-03-14 12:53:46 -07001930 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001931 manager()->DeregisterService(mock_service);
1932}
1933
Paul Stewart13ed2252012-03-21 12:52:46 -07001934TEST_F(ManagerTest, GetServiceWithGUID) {
1935 scoped_refptr<MockService> mock_service0(
1936 new NiceMock<MockService>(control_interface(),
1937 dispatcher(),
1938 metrics(),
1939 manager()));
1940
1941 scoped_refptr<MockService> mock_service1(
1942 new NiceMock<MockService>(control_interface(),
1943 dispatcher(),
1944 metrics(),
1945 manager()));
1946
Paul Stewartcb59fed2012-03-21 21:14:46 -07001947 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1948 .Times(0);
1949 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1950 .Times(0);
1951
Paul Stewart13ed2252012-03-21 12:52:46 -07001952 manager()->RegisterService(mock_service0);
1953 manager()->RegisterService(mock_service1);
1954
1955 const string kGUID0 = "GUID0";
1956 const string kGUID1 = "GUID1";
1957
1958 {
1959 Error error;
1960 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1961 EXPECT_FALSE(error.IsSuccess());
1962 EXPECT_FALSE(service);
1963 }
1964
1965 KeyValueStore args;
1966 args.SetString(flimflam::kGuidProperty, kGUID1);
1967
1968 {
1969 Error error;
1970 ServiceRefPtr service = manager()->GetService(args, &error);
1971 EXPECT_EQ(Error::kInvalidArguments, error.type());
1972 EXPECT_FALSE(service);
1973 }
1974
1975 mock_service0->set_guid(kGUID0);
1976 mock_service1->set_guid(kGUID1);
1977
1978 {
1979 Error error;
1980 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1981 EXPECT_TRUE(error.IsSuccess());
1982 EXPECT_EQ(mock_service0.get(), service.get());
1983 }
1984
1985 {
1986 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07001987 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
1988 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07001989 ServiceRefPtr service = manager()->GetService(args, &error);
1990 EXPECT_TRUE(error.IsSuccess());
1991 EXPECT_EQ(mock_service1.get(), service.get());
1992 }
1993
1994 manager()->DeregisterService(mock_service0);
1995 manager()->DeregisterService(mock_service1);
1996}
1997
Gary Morain028545d2012-04-07 14:55:52 -07001998
1999TEST_F(ManagerTest, CalculateStateOffline) {
2000 MockMetrics mock_metrics;
2001 manager()->set_metrics(&mock_metrics);
2002 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2003 .Times(AnyNumber());
2004 scoped_refptr<MockService> mock_service0(
2005 new NiceMock<MockService>(control_interface(),
2006 dispatcher(),
2007 metrics(),
2008 manager()));
2009
2010 scoped_refptr<MockService> mock_service1(
2011 new NiceMock<MockService>(control_interface(),
2012 dispatcher(),
2013 metrics(),
2014 manager()));
2015
2016 EXPECT_CALL(*mock_service0.get(), IsConnected())
2017 .WillRepeatedly(Return(false));
2018 EXPECT_CALL(*mock_service1.get(), IsConnected())
2019 .WillRepeatedly(Return(false));
2020
2021 manager()->RegisterService(mock_service0);
2022 manager()->RegisterService(mock_service1);
2023
2024 EXPECT_EQ("offline", manager()->CalculateState(NULL));
2025
2026 manager()->DeregisterService(mock_service0);
2027 manager()->DeregisterService(mock_service1);
2028}
2029
2030TEST_F(ManagerTest, CalculateStateOnline) {
2031 MockMetrics mock_metrics;
2032 manager()->set_metrics(&mock_metrics);
2033 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2034 .Times(AnyNumber());
2035 scoped_refptr<MockService> mock_service0(
2036 new NiceMock<MockService>(control_interface(),
2037 dispatcher(),
2038 metrics(),
2039 manager()));
2040
2041 scoped_refptr<MockService> mock_service1(
2042 new NiceMock<MockService>(control_interface(),
2043 dispatcher(),
2044 metrics(),
2045 manager()));
2046
2047 EXPECT_CALL(*mock_service0.get(), IsConnected())
2048 .WillRepeatedly(Return(false));
2049 EXPECT_CALL(*mock_service1.get(), IsConnected())
2050 .WillRepeatedly(Return(true));
2051 EXPECT_CALL(*mock_service0.get(), state())
2052 .WillRepeatedly(Return(Service::kStateIdle));
2053 EXPECT_CALL(*mock_service1.get(), state())
2054 .WillRepeatedly(Return(Service::kStateConnected));
2055
2056 manager()->RegisterService(mock_service0);
2057 manager()->RegisterService(mock_service1);
2058
2059 EXPECT_EQ("online", manager()->CalculateState(NULL));
2060
2061 manager()->DeregisterService(mock_service0);
2062 manager()->DeregisterService(mock_service1);
2063}
2064
Paul Stewart10e9e4e2012-04-26 19:46:28 -07002065TEST_F(ManagerTest, StartupPortalList) {
2066 // Simulate loading value from the default profile.
2067 const string kProfileValue("wifi,vpn");
2068 manager()->props_.check_portal_list = kProfileValue;
2069
2070 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
2071 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2072 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2073
2074 const string kStartupValue("cellular,ethernet");
2075 manager()->SetStartupPortalList(kStartupValue);
2076 // Ensure profile value is not overwritten, so when we save the default
2077 // profile, the correct value will still be written.
2078 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
2079
2080 // However we should read back a different list.
2081 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
2082 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2083 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2084
2085 const string kRuntimeValue("ppp");
2086 // Setting a runtime value over the control API should overwrite both
2087 // the profile value and what we read back.
2088 Error error;
2089 manager()->mutable_store()->SetStringProperty(
2090 flimflam::kCheckPortalListProperty,
2091 kRuntimeValue,
2092 &error);
2093 ASSERT_TRUE(error.IsSuccess());
2094 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
2095 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
2096 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2097 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
2098}
2099
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002100TEST_F(ManagerTest, EnableTechnology) {
2101 Error error(Error::kOperationInitiated);
2102 ResultCallback callback;
2103 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2104 EXPECT_TRUE(error.IsSuccess());
2105
2106 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2107 .WillByDefault(Return(true));
2108
2109 manager()->RegisterDevice(mock_devices_[0]);
2110
2111 // Device is enabled, so expect operation is successful.
2112 mock_devices_[0]->enabled_ = true;
2113 error.Populate(Error::kOperationInitiated);
2114 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2115 EXPECT_TRUE(error.IsSuccess());
2116
2117 // Device is disabled, so expect operation in progress.
2118 mock_devices_[0]->enabled_ = false;
2119 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
2120 error.Populate(Error::kOperationInitiated);
2121 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2122 EXPECT_TRUE(error.IsOngoing());
2123}
2124
2125TEST_F(ManagerTest, DisableTechnology) {
2126 Error error(Error::kOperationInitiated);
2127 ResultCallback callback;
2128 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2129 EXPECT_TRUE(error.IsSuccess());
2130
2131 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2132 .WillByDefault(Return(true));
2133
2134 manager()->RegisterDevice(mock_devices_[0]);
2135
2136 // Device is disabled, so expect operation is successful.
2137 error.Populate(Error::kOperationInitiated);
2138 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2139 EXPECT_TRUE(error.IsSuccess());
2140
2141 // Device is enabled, so expect operation in progress.
2142 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
2143 mock_devices_[0]->enabled_ = true;
2144 error.Populate(Error::kOperationInitiated);
2145 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2146 EXPECT_TRUE(error.IsOngoing());
2147}
2148
2149
Chris Masone9be4a9d2011-05-16 15:44:09 -07002150} // namespace shill