blob: f70327700714f5d308ddd09d84ec7d55b209431a [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 Stewart7f5ad572012-06-04 15:18:54 -070053using ::testing::DoAll;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070054using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070055using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070056using ::testing::NiceMock;
57using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070058using ::testing::ReturnRef;
Paul Stewart7f5ad572012-06-04 15:18:54 -070059using ::testing::SaveArg;
Gaurav Shah435de2c2011-11-17 19:01:07 -080060using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080061using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070062using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070063
Chris Masone3bd3c8c2011-06-13 08:20:26 -070064class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070065 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070066 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070067 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070068 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080069 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070070 manager(),
71 "wifi0",
72 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080073 4)),
74 device_info_(new NiceMock<MockDeviceInfo>(
75 control_interface(),
76 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080077 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080078 reinterpret_cast<Manager*>(NULL))),
79 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070080 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
81 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080082 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070083 manager(),
84 "null0",
85 "addr0",
86 0));
87 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
88 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080089 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070090 manager(),
91 "null1",
92 "addr1",
93 1));
94 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
95 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080096 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070097 manager(),
98 "null2",
99 "addr2",
100 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800101 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
102 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800103 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -0800104 manager(),
105 "null3",
106 "addr3",
107 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700108 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800109
110 // Replace the manager's adaptor with a quieter one, and one
111 // we can do EXPECT*() against. Passes ownership.
112 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700113 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700114 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700115
Paul Stewartfdd16072011-09-16 12:41:35 -0700116 bool IsDeviceRegistered(const DeviceRefPtr &device,
117 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700118 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700119 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700120 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700121 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700122 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700123
Paul Stewarta849a3d2011-11-03 05:54:09 -0700124 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
125 manager->profiles_.push_back(profile);
126 }
127
Paul Stewart75225512012-01-26 22:51:33 -0800128 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
129 return manager->ephemeral_profile_;
130 }
131
Chris Masone6515aab2011-10-12 16:19:09 -0700132 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
133 Profile::Identifier id("rather", "irrelevant");
134 scoped_ptr<Profile> profile(new Profile(control_interface(),
135 manager,
136 id,
137 "",
138 false));
139 FilePath final_path(storage_path());
140 final_path = final_path.Append("test.profile");
141 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
142 storage->set_path(final_path);
143 if (!storage->Open())
144 return NULL;
145 profile->set_storage(storage.release()); // Passes ownership.
146 return profile.release();
147 }
148
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700149 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
150 const string &profile_identifier,
151 const string &service_name) {
152 GLib glib;
153 KeyFileStore store(&glib);
154 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
155 return store.Open() &&
156 store.SetString(service_name, "rather", "irrelevant") &&
157 store.Close();
158 }
159
160 Error::Type TestCreateProfile(Manager *manager, const string &name) {
161 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800162 string path;
163 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700164 return error.type();
165 }
166
167 Error::Type TestPopAnyProfile(Manager *manager) {
168 Error error;
169 manager->PopAnyProfile(&error);
170 return error.type();
171 }
172
173 Error::Type TestPopProfile(Manager *manager, const string &name) {
174 Error error;
175 manager->PopProfile(name, &error);
176 return error.type();
177 }
178
179 Error::Type TestPushProfile(Manager *manager, const string &name) {
180 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800181 string path;
182 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700183 return error.type();
184 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000185
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700186 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000187 typedef scoped_refptr<MockService> MockServiceRefPtr;
188
189 MockServiceRefPtr MakeAutoConnectableService() {
190 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
191 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800192 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000193 manager());
194 service->MakeFavorite();
195 service->set_connectable(true);
196 return service;
197 }
198
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700199 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700200 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800201 scoped_ptr<MockDeviceInfo> device_info_;
202
203 // This pointer is owned by the manager, and only tracked here for EXPECT*()
204 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700205};
206
Paul Stewart22aa71b2011-09-16 12:15:11 -0700207bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
208 return (svc0.get() == manager()->services_[0].get() &&
209 svc1.get() == manager()->services_[1].get());
210}
211
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700212TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700213 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
214 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700215}
216
Chris Masone9be4a9d2011-05-16 15:44:09 -0700217TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700218 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700219 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700220 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700221 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700222 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700223 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700224
Paul Stewart22aa71b2011-09-16 12:15:11 -0700225 manager()->RegisterDevice(mock_devices_[0]);
226 manager()->RegisterDevice(mock_devices_[1]);
227 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700228
Paul Stewart22aa71b2011-09-16 12:15:11 -0700229 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
230 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
231 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700232}
233
Paul Stewarta41e38d2011-11-11 07:47:29 -0800234TEST_F(ManagerTest, DeviceRegistrationAndStart) {
235 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500236 mock_devices_[0]->enabled_persistent_ = true;
237 mock_devices_[1]->enabled_persistent_ = false;
238 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800239 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500240 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800241 .Times(0);
242 manager()->RegisterDevice(mock_devices_[0]);
243 manager()->RegisterDevice(mock_devices_[1]);
244}
245
246TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
247 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
248 DeviceRefPtr device_ref(mock_devices_[0].get());
249 AdoptProfile(manager(), profile); // Passes ownership.
250 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
251 EXPECT_CALL(*profile, Save());
252 manager()->RegisterDevice(mock_devices_[0]);
253}
254
Chris Masone9be4a9d2011-05-16 15:44:09 -0700255TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700256 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700257 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700258 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700259 .WillByDefault(Return(true));
260
Gaurav Shah435de2c2011-11-17 19:01:07 -0800261 manager()->RegisterDevice(mock_devices_[0]);
262 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700263
Paul Stewart22aa71b2011-09-16 12:15:11 -0700264 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
265 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700266
Eric Shienbrood9a245532012-03-07 14:20:39 -0500267 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800268 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700269 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700270
Eric Shienbrood9a245532012-03-07 14:20:39 -0500271 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800272 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700273 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700274}
275
276TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700277 // It's much easier and safer to use a real GLib for this test.
278 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700279 Manager manager(control_interface(),
280 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800281 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700282 &glib,
283 run_path(),
284 storage_path(),
285 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700286 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
287 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700288 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700289
Chris Masone9be4a9d2011-05-16 15:44:09 -0700290 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700291 new NiceMock<MockService>(control_interface(),
292 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800293 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700294 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700295 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700296 new NiceMock<MockService>(control_interface(),
297 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800298 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700299 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700300
mukesh agrawal51a7e932011-07-27 16:18:26 -0700301 string service1_name(mock_service->UniqueName());
302 string service2_name(mock_service2->UniqueName());
303
304 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
305 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700306 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700307 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700308 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700309 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700310 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700311
Chris Masone9d779932011-08-25 16:33:41 -0700312 manager.RegisterService(mock_service);
313 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700314
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800315 Error error;
316 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700317 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700318 EXPECT_EQ(2, ids.size());
319 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
320 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700321
Chris Masone9d779932011-08-25 16:33:41 -0700322 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
323 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
324
325 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700326}
327
Chris Masone6515aab2011-10-12 16:19:09 -0700328TEST_F(ManagerTest, RegisterKnownService) {
329 // It's much easier and safer to use a real GLib for this test.
330 GLib glib;
331 Manager manager(control_interface(),
332 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800333 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700334 &glib,
335 run_path(),
336 storage_path(),
337 string());
338 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
339 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700340 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700341 {
342 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
343 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800344 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700345 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700346 ASSERT_TRUE(profile->AdoptService(service1));
347 ASSERT_TRUE(profile->ContainsService(service1));
348 } // Force destruction of service1.
349
350 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
351 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800352 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700353 &manager));
354 manager.RegisterService(service2);
355 EXPECT_EQ(service2->profile().get(), profile.get());
356 manager.Stop();
357}
358
359TEST_F(ManagerTest, RegisterUnknownService) {
360 // It's much easier and safer to use a real GLib for this test.
361 GLib glib;
362 Manager manager(control_interface(),
363 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800364 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700365 &glib,
366 run_path(),
367 storage_path(),
368 string());
369 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
370 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700371 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700372 {
373 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
374 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800375 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700376 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700377 ASSERT_TRUE(profile->AdoptService(service1));
378 ASSERT_TRUE(profile->ContainsService(service1));
379 } // Force destruction of service1.
380 scoped_refptr<MockService> mock_service2(
381 new NiceMock<MockService>(control_interface(),
382 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800383 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700384 &manager));
385 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
386 .WillRepeatedly(Return(mock_service2->UniqueName()));
387 manager.RegisterService(mock_service2);
388 EXPECT_NE(mock_service2->profile().get(), profile.get());
389 manager.Stop();
390}
391
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000392TEST_F(ManagerTest, DeregisterUnregisteredService) {
393 // WiFi assumes that it can deregister a service that is not
394 // registered. (E.g. a hidden service can be deregistered when it
395 // loses its last endpoint, and again when WiFi is Stop()-ed.)
396 //
397 // So test that doing so doesn't cause a crash.
398 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
399 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800400 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000401 manager());
402 manager()->DeregisterService(service);
403}
404
Chris Masonea8a2c252011-06-27 22:16:30 -0700405TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700406 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700407 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700408 map<string, ::DBus::Variant> props;
409 Error error(Error::kInvalidProperty, "");
410 {
411 ::DBus::Error dbus_error;
412 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700413 manager()->mutable_store()->SetStringProperty(
414 flimflam::kCheckPortalListProperty,
415 expected,
416 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700417 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700418 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
419 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
420 expected);
421 }
422 {
423 ::DBus::Error dbus_error;
424 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700425 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
426 expected,
427 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700428 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700429 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
430 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
431 expected);
432 }
433}
434
Chris Masone3c3f6a12011-07-01 10:01:41 -0700435TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700436 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700437 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800438 manager()->RegisterDevice(mock_devices_[0]);
439 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700440 {
441 map<string, ::DBus::Variant> props;
442 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700443 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700444 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
445 Strings devices =
446 props[flimflam::kDevicesProperty].operator vector<string>();
447 EXPECT_EQ(2, devices.size());
448 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700449}
450
mukesh agrawal2366eed2012-03-20 18:21:50 -0700451TEST_F(ManagerTest, GetServicesProperty) {
452 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
453 AdoptProfile(manager(), profile);
454 map<string, ::DBus::Variant> props;
455 ::DBus::Error dbus_error;
456 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
457 map<string, ::DBus::Variant>::const_iterator prop =
458 props.find(flimflam::kServicesProperty);
459 ASSERT_FALSE(prop == props.end());
460 const ::DBus::Variant &variant = prop->second;
461 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
462}
463
Chris Masone6791a432011-07-12 13:23:19 -0700464TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700465 Manager manager(control_interface(),
466 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800467 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700468 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700469 run_path(),
470 storage_path(),
471 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700472 scoped_refptr<MockService> s2(new MockService(control_interface(),
473 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800474 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700475 &manager));
476 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700477 {
Chris Masone6515aab2011-10-12 16:19:09 -0700478 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700479 ProfileRefPtr profile(
480 new Profile(control_interface(), &manager, id, "", false));
481 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700482 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
Chris Masone6515aab2011-10-12 16:19:09 -0700483 .WillRepeatedly(Return(true));
484 EXPECT_CALL(*storage, Flush())
485 .Times(AnyNumber())
486 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700487 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700488 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700489 }
Chris Masone6515aab2011-10-12 16:19:09 -0700490 // Create a profile that already has |s2| in it.
491 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
Paul Stewart451aa7f2012-04-11 19:07:58 -0700492 EXPECT_TRUE(profile->AdoptService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700493
Chris Masone6515aab2011-10-12 16:19:09 -0700494 // Now, move the Service |s2| to another profile.
495 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
496 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700497
498 // Force destruction of the original Profile, to ensure that the Service
499 // is kept alive and populated with data.
500 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700501 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700502 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700503}
504
Paul Stewart7f61e522012-03-22 11:13:45 -0700505TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
506 scoped_refptr<MockProfile> mock_profile(
507 new MockProfile(control_interface(), manager(), ""));
508 const string kProfileName("profile0");
509 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
510 .WillRepeatedly(Return(kProfileName));
511 AdoptProfile(manager(), mock_profile);
512
513 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
514 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
515 EXPECT_EQ(mock_profile.get(), profile.get());
516}
517
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800518TEST_F(ManagerTest, SetProfileForService) {
519 scoped_refptr<MockProfile> profile0(
520 new MockProfile(control_interface(), manager(), ""));
521 string profile_name0("profile0");
522 EXPECT_CALL(*profile0, GetRpcIdentifier())
523 .WillRepeatedly(Return(profile_name0));
524 AdoptProfile(manager(), profile0);
525 scoped_refptr<MockService> service(new MockService(control_interface(),
526 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800527 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800528 manager()));
529 service->set_profile(profile0);
530
531 {
532 Error error;
533 manager()->SetProfileForService(service, "foo", &error);
534 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700535 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800536 }
537
538 {
539 Error error;
540 manager()->SetProfileForService(service, profile_name0, &error);
541 EXPECT_EQ(Error::kInvalidArguments, error.type());
542 EXPECT_EQ("Service is already connected to this profile", error.message());
543 }
544
545 scoped_refptr<MockProfile> profile1(
546 new MockProfile(control_interface(), manager(), ""));
547 string profile_name1("profile1");
548 EXPECT_CALL(*profile1, GetRpcIdentifier())
549 .WillRepeatedly(Return(profile_name1));
550 AdoptProfile(manager(), profile1);
551
552 {
553 Error error;
554 EXPECT_CALL(*profile1, AdoptService(_))
555 .WillOnce(Return(true));
556 EXPECT_CALL(*profile0, AbandonService(_))
557 .WillOnce(Return(true));
558 manager()->SetProfileForService(service, profile_name1, &error);
559 EXPECT_TRUE(error.IsSuccess());
560 }
561}
562
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700563TEST_F(ManagerTest, CreateProfile) {
564 // It's much easier to use real Glib here since we want the storage
565 // side-effects.
566 GLib glib;
567 ScopedTempDir temp_dir;
568 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
569
570 Manager manager(control_interface(),
571 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800572 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700573 &glib,
574 run_path(),
575 storage_path(),
576 temp_dir.path().value());
577
578 // Invalid name should be rejected.
579 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
580
Paul Stewartd0a3b812012-03-28 22:48:22 -0700581 // A profile with invalid characters in it should similarly be rejected.
582 EXPECT_EQ(Error::kInvalidArguments,
583 TestCreateProfile(&manager, "valid_profile"));
584
585 // We should be able to create a machine profile.
586 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, "valid"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700587
Gary Morainb672d352012-04-25 09:19:06 -0700588 // We should succeed in creating a valid user profile. Verify the returned
589 // path.
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700590 const char kProfile[] = "~user/profile";
Gary Morainb672d352012-04-25 09:19:06 -0700591 {
592 Error error;
593 string path;
594 manager.CreateProfile(kProfile, &path, &error);
595 EXPECT_EQ(Error::kSuccess, error.type());
596 EXPECT_EQ("/profile_rpc", path);
597 }
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700598
599 // We should fail in creating it a second time (already exists).
600 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
601}
602
603TEST_F(ManagerTest, PushPopProfile) {
604 // It's much easier to use real Glib in creating a Manager for this
605 // test here since we want the storage side-effects.
606 GLib glib;
607 ScopedTempDir temp_dir;
608 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
609 Manager manager(control_interface(),
610 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800611 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700612 &glib,
613 run_path(),
614 storage_path(),
615 temp_dir.path().value());
616
617 // Pushing an invalid profile should fail.
618 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
619
Paul Stewartd0a3b812012-03-28 22:48:22 -0700620 // Pushing a default profile that does not exist should fail.
621 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, "default"));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700622
623 const char kProfile0[] = "~user/profile0";
624 const char kProfile1[] = "~user/profile1";
625
626 // Create a couple of profiles.
627 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
628 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
629
630 // Push these profiles on the stack.
631 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
632 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
633
634 // Pushing a profile a second time should fail.
635 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
636 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
637
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800638 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700639 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800640 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700641
642 // Make sure a profile name that doesn't exist fails.
643 const char kProfile2Id[] = "profile2";
644 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
645 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
646
647 // Create a new service, with a specific storage name.
648 scoped_refptr<MockService> service(
649 new NiceMock<MockService>(control_interface(),
650 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800651 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700652 &manager));
653 const char kServiceName[] = "service_storage_name";
654 EXPECT_CALL(*service.get(), GetStorageIdentifier())
655 .WillRepeatedly(Return(kServiceName));
656 EXPECT_CALL(*service.get(), Load(_))
657 .WillRepeatedly(Return(true));
658
659 // Add this service to the manager -- it should end up in the ephemeral
660 // profile.
661 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800662 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700663
664 // Create storage for a profile that contains the service storage name.
665 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
666 kServiceName));
667
668 // When we push the profile, the service should move away from the
669 // ephemeral profile to this new profile since it has an entry for
670 // this service.
671 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800672 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700673 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
674
675 // Insert another profile that should supersede ownership of the service.
676 const char kProfile3Id[] = "profile3";
677 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
678 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
679 kServiceName));
680 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
681 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
682
683 // Popping an invalid profile name should fail.
684 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
685
686 // Popping an profile that is not at the top of the stack should fail.
687 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
688
689 // Popping the top profile should succeed.
690 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
691
692 // Moreover the service should have switched profiles to profile 2.
693 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
694
695 // Popping the top profile should succeed.
696 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
697
698 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800699 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700700
701 // Pop the remaining two services off the stack.
702 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
703 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
704
705 // Next pop should fail with "stack is empty".
706 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
Paul Stewartd0a3b812012-03-28 22:48:22 -0700707
708 const char kMachineProfile0[] = "machineprofile0";
709 const char kMachineProfile1[] = "machineprofile1";
710 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile0));
711 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kMachineProfile1));
712
713 // Should be able to push a machine profile.
714 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile0));
715
716 // Should be able to push a user profile atop a machine profile.
717 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
718
719 // Pushing a system-wide profile on top of a user profile should fail.
720 EXPECT_EQ(Error::kInvalidArguments,
721 TestPushProfile(&manager, kMachineProfile1));
722
723 // However if we pop the user profile, we should be able stack another
724 // machine profile on.
725 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
726 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kMachineProfile1));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700727}
728
Paul Stewarte73d05c2012-03-29 16:26:05 -0700729TEST_F(ManagerTest, RemoveProfile) {
730 // It's much easier to use real Glib in creating a Manager for this
731 // test here since we want the storage side-effects.
732 GLib glib;
733 ScopedTempDir temp_dir;
734 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
735 Manager manager(control_interface(),
736 dispatcher(),
737 metrics(),
738 &glib,
739 run_path(),
740 storage_path(),
741 temp_dir.path().value());
742
743 const char kProfile0[] = "profile0";
744 FilePath profile_path(
745 FilePath(storage_path()).Append(string(kProfile0) + ".profile"));
746
747 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
748 ASSERT_TRUE(file_util::PathExists(profile_path));
749
750 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
751
752 // Remove should fail since the profile is still on the stack.
753 {
754 Error error;
755 manager.RemoveProfile(kProfile0, &error);
756 EXPECT_EQ(Error::kInvalidArguments, error.type());
757 }
758
759 // Profile path should still exist.
760 EXPECT_TRUE(file_util::PathExists(profile_path));
761
762 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
763
764 // This should succeed now that the profile is off the stack.
765 {
766 Error error;
767 manager.RemoveProfile(kProfile0, &error);
768 EXPECT_EQ(Error::kSuccess, error.type());
769 }
770
771 // Profile path should no longer exist.
772 EXPECT_FALSE(file_util::PathExists(profile_path));
773
774 // Another remove succeeds, due to a foible in file_util::Delete --
775 // it is not an error to delete a file that does not exist.
776 {
777 Error error;
778 manager.RemoveProfile(kProfile0, &error);
779 EXPECT_EQ(Error::kSuccess, error.type());
780 }
781
782 // Let's create an error case that will "work". Create a non-empty
783 // directory in the place of the profile pathname.
784 ASSERT_TRUE(file_util::CreateDirectory(profile_path.Append("foo")));
785 {
786 Error error;
787 manager.RemoveProfile(kProfile0, &error);
788 EXPECT_EQ(Error::kOperationFailed, error.type());
789 }
790}
791
Paul Stewart75225512012-01-26 22:51:33 -0800792// Use this matcher instead of passing RefPtrs directly into the arguments
793// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
794// system teardown.
795MATCHER_P(IsRefPtrTo, ref_address, "") {
796 return arg.get() == ref_address;
797}
798
799TEST_F(ManagerTest, HandleProfileEntryDeletion) {
800 MockServiceRefPtr s_not_in_profile(
801 new NiceMock<MockService>(control_interface(),
802 dispatcher(),
803 metrics(),
804 manager()));
805 MockServiceRefPtr s_not_in_group(
806 new NiceMock<MockService>(control_interface(),
807 dispatcher(),
808 metrics(),
809 manager()));
810 MockServiceRefPtr s_configure_fail(
811 new NiceMock<MockService>(control_interface(),
812 dispatcher(),
813 metrics(),
814 manager()));
815 MockServiceRefPtr s_configure_succeed(
816 new NiceMock<MockService>(control_interface(),
817 dispatcher(),
818 metrics(),
819 manager()));
820
821 string entry_name("entry_name");
822 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
823 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
824 .WillRepeatedly(Return("not_entry_name"));
825 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
826 .WillRepeatedly(Return(entry_name));
827 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
828 .WillRepeatedly(Return(entry_name));
829
830 manager()->RegisterService(s_not_in_profile);
831 manager()->RegisterService(s_not_in_group);
832 manager()->RegisterService(s_configure_fail);
833 manager()->RegisterService(s_configure_succeed);
834
835 scoped_refptr<MockProfile> profile0(
836 new StrictMock<MockProfile>(control_interface(), manager(), ""));
837 scoped_refptr<MockProfile> profile1(
838 new StrictMock<MockProfile>(control_interface(), manager(), ""));
839
840 s_not_in_group->set_profile(profile1);
841 s_configure_fail->set_profile(profile1);
842 s_configure_succeed->set_profile(profile1);
843
844 AdoptProfile(manager(), profile0);
845 AdoptProfile(manager(), profile1);
846
847 // No services are a member of this profile.
848 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
849
850 // No services that are members of this profile have this entry name.
851 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
852
853 // Only services that are members of the profile and group will be abandoned.
854 EXPECT_CALL(*profile1.get(),
855 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
856 EXPECT_CALL(*profile1.get(),
857 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
858 EXPECT_CALL(*profile1.get(),
859 AbandonService(IsRefPtrTo(s_configure_fail.get())))
860 .WillOnce(Return(true));
861 EXPECT_CALL(*profile1.get(),
862 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
863 .WillOnce(Return(true));
864
865 // Never allow services to re-join profile1.
866 EXPECT_CALL(*profile1.get(), ConfigureService(_))
867 .WillRepeatedly(Return(false));
868
869 // Only allow one of the members of the profile and group to successfully
870 // join profile0.
871 EXPECT_CALL(*profile0.get(),
872 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
873 EXPECT_CALL(*profile0.get(),
874 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
875 EXPECT_CALL(*profile0.get(),
876 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
877 .WillOnce(Return(false));
878 EXPECT_CALL(*profile0.get(),
879 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
880 .WillOnce(Return(true));
881
882 // Expect the failed-to-configure service to have Unload() called on it.
883 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
884 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
885 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
886 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
887
888 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
889
890 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
891 EXPECT_EQ(profile1, s_not_in_group->profile());
892 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
893
894 // Since we are using a MockProfile, the profile does not actually change,
895 // since ConfigureService was not actually called on the service.
896 EXPECT_EQ(profile1, s_configure_succeed->profile());
897}
898
Paul Stewart65512e12012-03-26 18:01:08 -0700899TEST_F(ManagerTest, HandleProfileEntryDeletionWithUnload) {
900 MockServiceRefPtr s_will_remove0(
901 new NiceMock<MockService>(control_interface(),
902 dispatcher(),
903 metrics(),
904 manager()));
905 MockServiceRefPtr s_will_remove1(
906 new NiceMock<MockService>(control_interface(),
907 dispatcher(),
908 metrics(),
909 manager()));
910 MockServiceRefPtr s_will_not_remove0(
911 new NiceMock<MockService>(control_interface(),
912 dispatcher(),
913 metrics(),
914 manager()));
915 MockServiceRefPtr s_will_not_remove1(
916 new NiceMock<MockService>(control_interface(),
917 dispatcher(),
918 metrics(),
919 manager()));
920
921 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
922 .Times(4); // Once for each registration.
923
924 string entry_name("entry_name");
925 EXPECT_CALL(*s_will_remove0.get(), GetStorageIdentifier())
926 .WillRepeatedly(Return(entry_name));
927 EXPECT_CALL(*s_will_remove1.get(), GetStorageIdentifier())
928 .WillRepeatedly(Return(entry_name));
929 EXPECT_CALL(*s_will_not_remove0.get(), GetStorageIdentifier())
930 .WillRepeatedly(Return(entry_name));
931 EXPECT_CALL(*s_will_not_remove1.get(), GetStorageIdentifier())
932 .WillRepeatedly(Return(entry_name));
933
934 manager()->RegisterService(s_will_remove0);
935 manager()->RegisterService(s_will_not_remove0);
936 manager()->RegisterService(s_will_remove1);
937 manager()->RegisterService(s_will_not_remove1);
938
939 // One for each service added above.
940 ASSERT_EQ(4, manager()->services_.size());
941
942 scoped_refptr<MockProfile> profile(
943 new StrictMock<MockProfile>(control_interface(), manager(), ""));
944
945 s_will_remove0->set_profile(profile);
946 s_will_remove1->set_profile(profile);
947 s_will_not_remove0->set_profile(profile);
948 s_will_not_remove1->set_profile(profile);
949
950 AdoptProfile(manager(), profile);
951
952 // Deny any of the services re-entry to the profile.
953 EXPECT_CALL(*profile, ConfigureService(_))
954 .WillRepeatedly(Return(false));
955
956 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove0)))
957 .WillOnce(Return(true));
958 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_remove1)))
959 .WillOnce(Return(true));
960 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove0)))
961 .WillOnce(Return(true));
962 EXPECT_CALL(*profile, AbandonService(ServiceRefPtr(s_will_not_remove1)))
963 .WillOnce(Return(true));
964
965 EXPECT_CALL(*s_will_remove0, Unload())
966 .WillOnce(Return(true));
967 EXPECT_CALL(*s_will_remove1, Unload())
968 .WillOnce(Return(true));
969 EXPECT_CALL(*s_will_not_remove0, Unload())
970 .WillOnce(Return(false));
971 EXPECT_CALL(*s_will_not_remove1, Unload())
972 .WillOnce(Return(false));
973
974
975 // This will cause all the profiles to be unloaded.
976 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile, entry_name));
977
978 // 2 of the 4 services added above should have been unregistered and
979 // removed, leaving 2.
980 EXPECT_EQ(2, manager()->services_.size());
981 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
982 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
983}
984
985TEST_F(ManagerTest, PopProfileWithUnload) {
986 MockServiceRefPtr s_will_remove0(
987 new NiceMock<MockService>(control_interface(),
988 dispatcher(),
989 metrics(),
990 manager()));
991 MockServiceRefPtr s_will_remove1(
992 new NiceMock<MockService>(control_interface(),
993 dispatcher(),
994 metrics(),
995 manager()));
996 MockServiceRefPtr s_will_not_remove0(
997 new NiceMock<MockService>(control_interface(),
998 dispatcher(),
999 metrics(),
1000 manager()));
1001 MockServiceRefPtr s_will_not_remove1(
1002 new NiceMock<MockService>(control_interface(),
1003 dispatcher(),
1004 metrics(),
1005 manager()));
1006
1007 EXPECT_CALL(*metrics(), NotifyDefaultServiceChanged(NULL))
1008 .Times(5); // Once for each registration, and one after profile pop.
1009
1010 manager()->RegisterService(s_will_remove0);
1011 manager()->RegisterService(s_will_not_remove0);
1012 manager()->RegisterService(s_will_remove1);
1013 manager()->RegisterService(s_will_not_remove1);
1014
1015 // One for each service added above.
1016 ASSERT_EQ(4, manager()->services_.size());
1017
1018 scoped_refptr<MockProfile> profile0(
1019 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1020 scoped_refptr<MockProfile> profile1(
1021 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1022
1023 s_will_remove0->set_profile(profile1);
1024 s_will_remove1->set_profile(profile1);
1025 s_will_not_remove0->set_profile(profile1);
1026 s_will_not_remove1->set_profile(profile1);
1027
1028 AdoptProfile(manager(), profile0);
1029 AdoptProfile(manager(), profile1);
1030
1031 // Deny any of the services entry to profile0, so they will all be unloaded.
1032 EXPECT_CALL(*profile0, ConfigureService(_))
1033 .WillRepeatedly(Return(false));
1034
1035 EXPECT_CALL(*s_will_remove0, Unload())
1036 .WillOnce(Return(true));
1037 EXPECT_CALL(*s_will_remove1, Unload())
1038 .WillOnce(Return(true));
1039 EXPECT_CALL(*s_will_not_remove0, Unload())
1040 .WillOnce(Return(false));
1041 EXPECT_CALL(*s_will_not_remove1, Unload())
1042 .WillOnce(Return(false));
1043
1044 // This will pop profile1, which should cause all our profiles to unload.
1045 manager()->PopProfileInternal();
1046
1047 // 2 of the 4 services added above should have been unregistered and
1048 // removed, leaving 2.
1049 EXPECT_EQ(2, manager()->services_.size());
1050 EXPECT_EQ(s_will_not_remove0.get(), manager()->services_[0].get());
1051 EXPECT_EQ(s_will_not_remove1.get(), manager()->services_[1].get());
1052}
1053
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001054TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -07001055 {
1056 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001057 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1058 flimflam::kOfflineModeProperty,
1059 PropertyStoreTest::kBoolV,
1060 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001061 }
1062 {
1063 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001064 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1065 flimflam::kCountryProperty,
1066 PropertyStoreTest::kStringV,
1067 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -07001068 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001069 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001070 {
1071 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001072 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1073 flimflam::kCountryProperty,
1074 PropertyStoreTest::kBoolV,
1075 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001076 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001077 }
1078 {
1079 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001080 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
1081 flimflam::kOfflineModeProperty,
1082 PropertyStoreTest::kStringV,
1083 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001084 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001085 }
Chris Masoneb925cc82011-06-22 15:39:57 -07001086 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -07001087 {
1088 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001089 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -07001090 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -07001091 flimflam::kEnabledTechnologiesProperty,
1092 PropertyStoreTest::kStringsV,
1093 &error));
Chris Masone9d779932011-08-25 16:33:41 -07001094 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -07001095 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001096}
1097
mukesh agrawal32399322011-09-01 10:53:43 -07001098TEST_F(ManagerTest, RequestScan) {
1099 {
1100 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -07001101 manager()->RegisterDevice(mock_devices_[0].get());
1102 manager()->RegisterDevice(mock_devices_[1].get());
1103 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001104 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001105 EXPECT_CALL(*mock_devices_[0], Scan(_));
1106 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -07001107 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001108 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -07001109 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001110 }
1111
1112 {
1113 Error error;
Chris Masone9d779932011-08-25 16:33:41 -07001114 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -07001115 EXPECT_EQ(Error::kInvalidArguments, error.type());
1116 }
1117}
1118
Darin Petkovb65c2452012-02-23 15:17:06 +01001119TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001120 KeyValueStore args;
1121 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001122 manager()->GetService(args, &e);
1123 EXPECT_EQ(Error::kInvalidArguments, e.type());
1124 EXPECT_EQ("must specify service type", e.message());
1125}
1126
1127TEST_F(ManagerTest, GetServiceUnknownType) {
1128 KeyValueStore args;
1129 Error e;
1130 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
1131 manager()->GetService(args, &e);
1132 EXPECT_EQ(Error::kNotSupported, e.type());
1133 EXPECT_EQ("service type is unsupported", e.message());
1134}
1135
1136TEST_F(ManagerTest, GetServiceNoWifiDevice) {
1137 KeyValueStore args;
1138 Error e;
1139 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1140 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001141 EXPECT_EQ(Error::kInvalidArguments, e.type());
1142 EXPECT_EQ("no wifi devices available", e.message());
1143}
1144
Darin Petkovb65c2452012-02-23 15:17:06 +01001145TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001146 KeyValueStore args;
1147 Error e;
1148 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +01001149 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001150 manager()->RegisterDevice(mock_wifi_);
1151 EXPECT_CALL(*mock_wifi_, GetService(_, _))
1152 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +01001153 manager()->GetService(args, &e);
1154 EXPECT_TRUE(e.IsSuccess());
1155}
1156
Darin Petkov33af05c2012-02-28 10:10:30 +01001157TEST_F(ManagerTest, GetServiceVPNUnknownType) {
1158 KeyValueStore args;
1159 Error e;
1160 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001161 scoped_refptr<MockProfile> profile(
1162 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1163 AdoptProfile(manager(), profile);
Darin Petkov33af05c2012-02-28 10:10:30 +01001164 ServiceRefPtr service = manager()->GetService(args, &e);
1165 EXPECT_EQ(Error::kNotSupported, e.type());
1166 EXPECT_FALSE(service);
1167}
1168
Darin Petkovb65c2452012-02-23 15:17:06 +01001169TEST_F(ManagerTest, GetServiceVPN) {
1170 KeyValueStore args;
1171 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +01001172 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +01001173 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +01001174 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
1175 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Paul Stewart7f5ad572012-06-04 15:18:54 -07001176 scoped_refptr<MockProfile> profile(
1177 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1178 AdoptProfile(manager(), profile);
1179 ServiceRefPtr updated_service;
1180 EXPECT_CALL(*profile, UpdateService(_))
1181 .WillOnce(DoAll(SaveArg<0>(&updated_service), Return(true)));
1182 ServiceRefPtr configured_service;
1183 EXPECT_CALL(*profile, ConfigureService(_))
1184 .WillOnce(DoAll(SaveArg<0>(&configured_service), Return(true)));
Darin Petkov33af05c2012-02-28 10:10:30 +01001185 ServiceRefPtr service = manager()->GetService(args, &e);
1186 EXPECT_TRUE(e.IsSuccess());
1187 EXPECT_TRUE(service);
Paul Stewart7f5ad572012-06-04 15:18:54 -07001188 EXPECT_EQ(service, updated_service);
1189 EXPECT_EQ(service, configured_service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -07001190}
1191
Darin Petkovc63dcf02012-05-24 11:51:43 +02001192TEST_F(ManagerTest, GetServiceWiMaxNoNetworkId) {
1193 KeyValueStore args;
1194 Error e;
1195 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
1196 ServiceRefPtr service = manager()->GetService(args, &e);
1197 EXPECT_EQ(Error::kInvalidArguments, e.type());
1198 EXPECT_EQ("Missing WiMAX network id.", e.message());
1199 EXPECT_FALSE(service);
1200}
1201
Darin Petkovd1cd7972012-05-22 15:26:15 +02001202TEST_F(ManagerTest, GetServiceWiMax) {
1203 KeyValueStore args;
1204 Error e;
1205 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWimax);
Darin Petkovc63dcf02012-05-24 11:51:43 +02001206 args.SetString(WiMaxService::kNetworkIdProperty, "01234567");
1207 args.SetString(flimflam::kNameProperty, "WiMAX Network");
1208 ServiceRefPtr service = manager()->GetService(args, &e);
1209 EXPECT_TRUE(e.IsSuccess());
1210 EXPECT_TRUE(service);
Darin Petkovd1cd7972012-05-22 15:26:15 +02001211}
1212
Paul Stewart7f61e522012-03-22 11:13:45 -07001213TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
1214 // Manager calls ActiveProfile() so we need at least one profile installed.
1215 scoped_refptr<MockProfile> profile(
1216 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1217 AdoptProfile(manager(), profile);
1218
1219 KeyValueStore args;
1220 args.SetString(flimflam::kProfileProperty, "xxx");
1221 Error error;
1222 manager()->ConfigureService(args, &error);
1223 EXPECT_EQ(Error::kInvalidArguments, error.type());
1224 EXPECT_EQ("Invalid profile name xxx", error.message());
1225}
1226
1227TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
1228 // Manager calls ActiveProfile() so we need at least one profile installed.
1229 scoped_refptr<MockProfile> profile(
1230 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1231 AdoptProfile(manager(), profile);
1232
1233 KeyValueStore args;
1234 Error error;
1235 manager()->ConfigureService(args, &error);
1236 EXPECT_EQ(Error::kInvalidArguments, error.type());
1237 EXPECT_EQ("must specify service type", error.message());
1238}
1239
1240// A registered service in the ephemeral profile should be moved to the
1241// active profile as a part of configuration if no profile was explicitly
1242// specified.
1243TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
1244 scoped_refptr<MockProfile> profile(
1245 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1246
1247 AdoptProfile(manager(), profile); // This is now the active profile.
1248
1249 const std::vector<uint8_t> ssid;
1250 scoped_refptr<MockWiFiService> service(
1251 new NiceMock<MockWiFiService>(control_interface(),
1252 dispatcher(),
1253 metrics(),
1254 manager(),
1255 mock_wifi_,
1256 ssid,
1257 "",
1258 "",
1259 false));
1260
1261 manager()->RegisterService(service);
1262 service->set_profile(GetEphemeralProfile(manager()));
1263
1264 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1265 // the same device as that used above causes a refcounting loop.
1266 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1267 dispatcher(),
1268 metrics(),
1269 manager(),
1270 "wifi1",
1271 "addr5",
1272 5));
1273 manager()->RegisterDevice(wifi);
1274 EXPECT_CALL(*wifi, GetService(_, _))
1275 .WillOnce(Return(service));
1276 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
1277 .WillOnce(Return(true));
1278 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
1279 .WillOnce(Return(true));
1280
1281 KeyValueStore args;
1282 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1283 Error error;
1284 manager()->ConfigureService(args, &error);
1285 EXPECT_TRUE(error.IsSuccess());
1286}
1287
1288// If were configure a service that was already registered and explicitly
1289// specify a profile, it should be moved from the profile it was previously
1290// in to the specified profile if one was requested.
1291TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1292 scoped_refptr<MockProfile> profile0(
1293 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1294 scoped_refptr<MockProfile> profile1(
1295 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1296
1297 const string kProfileName0 = "profile0";
1298 const string kProfileName1 = "profile1";
1299
1300 EXPECT_CALL(*profile0, GetRpcIdentifier())
1301 .WillRepeatedly(Return(kProfileName0));
1302 EXPECT_CALL(*profile1, GetRpcIdentifier())
1303 .WillRepeatedly(Return(kProfileName1));
1304
1305 AdoptProfile(manager(), profile0);
1306 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1307
1308 const std::vector<uint8_t> ssid;
1309 scoped_refptr<MockWiFiService> service(
1310 new NiceMock<MockWiFiService>(control_interface(),
1311 dispatcher(),
1312 metrics(),
1313 manager(),
1314 mock_wifi_,
1315 ssid,
1316 "",
1317 "",
1318 false));
1319
1320 manager()->RegisterService(service);
1321 service->set_profile(profile1);
1322
1323 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1324 // the same device as that used above causes a refcounting loop.
1325 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1326 dispatcher(),
1327 metrics(),
1328 manager(),
1329 "wifi1",
1330 "addr5",
1331 5));
1332 manager()->RegisterDevice(wifi);
1333 EXPECT_CALL(*wifi, GetService(_, _))
1334 .WillOnce(Return(service));
1335 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1336 .WillOnce(Return(true));
1337 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1338 .WillOnce(Return(true));
1339 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1340 .WillOnce(Return(true));
1341
1342 KeyValueStore args;
1343 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1344 args.SetString(flimflam::kProfileProperty, kProfileName0);
1345 Error error;
1346 manager()->ConfigureService(args, &error);
1347 EXPECT_TRUE(error.IsSuccess());
1348 service->set_profile(NULL); // Breaks refcounting loop.
1349}
1350
1351// An unregistered service should remain unregistered, but its contents should
1352// be saved to the specified profile nonetheless.
1353TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1354 scoped_refptr<MockProfile> profile0(
1355 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1356 scoped_refptr<MockProfile> profile1(
1357 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1358
1359 const string kProfileName0 = "profile0";
1360 const string kProfileName1 = "profile1";
1361
1362 EXPECT_CALL(*profile0, GetRpcIdentifier())
1363 .WillRepeatedly(Return(kProfileName0));
1364 EXPECT_CALL(*profile1, GetRpcIdentifier())
1365 .WillRepeatedly(Return(kProfileName1));
1366
1367 AdoptProfile(manager(), profile0);
1368 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1369
1370 const std::vector<uint8_t> ssid;
1371 scoped_refptr<MockWiFiService> service(
1372 new NiceMock<MockWiFiService>(control_interface(),
1373 dispatcher(),
1374 metrics(),
1375 manager(),
1376 mock_wifi_,
1377 ssid,
1378 "",
1379 "",
1380 false));
1381
1382 service->set_profile(profile1);
1383
1384 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1385 // the same device as that used above causes a refcounting loop.
1386 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1387 dispatcher(),
1388 metrics(),
1389 manager(),
1390 "wifi1",
1391 "addr5",
1392 5));
1393 manager()->RegisterDevice(wifi);
1394 EXPECT_CALL(*wifi, GetService(_, _))
1395 .WillOnce(Return(service));
1396 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1397 .WillOnce(Return(true));
1398 EXPECT_CALL(*profile0, AdoptService(_))
1399 .Times(0);
1400 EXPECT_CALL(*profile1, AdoptService(_))
1401 .Times(0);
1402
1403 KeyValueStore args;
1404 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1405 args.SetString(flimflam::kProfileProperty, kProfileName0);
1406 Error error;
1407 manager()->ConfigureService(args, &error);
1408 EXPECT_TRUE(error.IsSuccess());
1409}
1410
Paul Stewart22aa71b2011-09-16 12:15:11 -07001411TEST_F(ManagerTest, TechnologyOrder) {
1412 Error error;
1413 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1414 string(flimflam::kTypeWifi), &error);
1415 ASSERT_TRUE(error.IsSuccess());
1416 EXPECT_EQ(manager()->GetTechnologyOrder(),
1417 string(flimflam::kTypeEthernet) + "," +
1418 string(flimflam::kTypeWifi));
1419
1420 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1421 string(flimflam::kTypeWifi), &error);
1422 ASSERT_FALSE(error.IsSuccess());
1423 EXPECT_EQ(Error::kInvalidArguments, error.type());
1424 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1425 string(flimflam::kTypeWifi),
1426 manager()->GetTechnologyOrder());
1427}
1428
1429TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001430 // TODO(quiche): Some of these tests would probably fit better in
1431 // service_unittest, since the actual comparison of Services is
1432 // implemented in Service. (crosbug.com/23370)
1433
Paul Stewart22aa71b2011-09-16 12:15:11 -07001434 scoped_refptr<MockService> mock_service0(
1435 new NiceMock<MockService>(control_interface(),
1436 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001437 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001438 manager()));
1439 scoped_refptr<MockService> mock_service1(
1440 new NiceMock<MockService>(control_interface(),
1441 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001442 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001443 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001444
1445 manager()->RegisterService(mock_service0);
1446 manager()->RegisterService(mock_service1);
1447
1448 // Services should already be sorted by UniqueName
1449 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1450
1451 // Asking explictly to sort services should not change anything
1452 manager()->SortServices();
1453 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1454
1455 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001456 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001457 manager()->UpdateService(mock_service1);
1458 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1459
1460 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001461 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001462 manager()->UpdateService(mock_service0);
1463 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1464
1465 // Technology
1466 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1467 .WillRepeatedly(Return(true));
1468 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1469 .WillRepeatedly(Return(true));
1470 // NB: Redefine default (false) return values so we don't use the default rule
1471 // which makes the logs noisier
1472 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1473 .WillRepeatedly(Return(false));
1474 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1475 .WillRepeatedly(Return(false));
1476
1477 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001478 // Default technology ordering should favor Ethernet over WiFi.
1479 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001480 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1481
1482 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1483 string(flimflam::kTypeEthernet), &error);
1484 EXPECT_TRUE(error.IsSuccess());
1485 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1486
Gaurav Shah435de2c2011-11-17 19:01:07 -08001487 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001488 mock_service0->set_priority(1);
1489 manager()->UpdateService(mock_service0);
1490 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1491
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001492 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001493 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001494 manager()->UpdateService(mock_service1);
1495 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1496
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001497 // Auto-connect.
1498 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001499 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001500 mock_service1->set_auto_connect(false);
1501 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001502 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1503
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001504 // Connectable.
1505 mock_service1->set_connectable(true);
1506 manager()->UpdateService(mock_service1);
1507 mock_service0->set_connectable(false);
1508 manager()->UpdateService(mock_service0);
1509 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1510
1511 // IsFailed.
1512 EXPECT_CALL(*mock_service0.get(), state())
1513 .WillRepeatedly(Return(Service::kStateIdle));
1514 EXPECT_CALL(*mock_service0.get(), IsFailed())
1515 .WillRepeatedly(Return(false));
1516 manager()->UpdateService(mock_service0);
1517 EXPECT_CALL(*mock_service0.get(), state())
1518 .WillRepeatedly(Return(Service::kStateFailure));
1519 EXPECT_CALL(*mock_service1.get(), IsFailed())
1520 .WillRepeatedly(Return(true));
1521 manager()->UpdateService(mock_service1);
1522 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1523
1524 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001525 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001526 .WillRepeatedly(Return(Service::kStateAssociating));
1527 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001528 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001529 manager()->UpdateService(mock_service1);
1530 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1531
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001532 // Connected.
1533 EXPECT_CALL(*mock_service0.get(), state())
1534 .WillRepeatedly(Return(Service::kStateConnected));
1535 EXPECT_CALL(*mock_service0.get(), IsConnected())
1536 .WillRepeatedly(Return(true));
1537 manager()->UpdateService(mock_service0);
1538 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1539
Paul Stewart22aa71b2011-09-16 12:15:11 -07001540 manager()->DeregisterService(mock_service0);
1541 manager()->DeregisterService(mock_service1);
1542}
1543
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001544TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001545 MockMetrics mock_metrics;
1546 manager()->set_metrics(&mock_metrics);
1547
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001548 scoped_refptr<MockService> mock_service0(
1549 new NiceMock<MockService>(control_interface(),
1550 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001551 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001552 manager()));
1553 scoped_refptr<MockService> mock_service1(
1554 new NiceMock<MockService>(control_interface(),
1555 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001556 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001557 manager()));
1558
1559 scoped_refptr<MockConnection> mock_connection0(
1560 new NiceMock<MockConnection>(device_info_.get()));
1561 scoped_refptr<MockConnection> mock_connection1(
1562 new NiceMock<MockConnection>(device_info_.get()));
1563
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001564 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001565 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001566 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001567 manager()->RegisterService(mock_service1);
1568
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001569 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1570 manager()->SortServices();
1571
1572 mock_service1->set_priority(1);
1573 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1574 manager()->SortServices();
1575
1576 mock_service1->set_priority(0);
1577 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1578 manager()->SortServices();
1579
Paul Stewartce4ec192012-03-14 12:53:46 -07001580 mock_service0->set_mock_connection(mock_connection0);
1581 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001582
1583 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001584 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001585 manager()->SortServices();
1586
1587 mock_service1->set_priority(1);
1588 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1589 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001590 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001591 manager()->SortServices();
1592
1593 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001594 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001595 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001596 manager()->DeregisterService(mock_service1);
1597
Paul Stewartce4ec192012-03-14 12:53:46 -07001598 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001599 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001600 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001601
1602 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1603 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001604}
1605
Gaurav Shah435de2c2011-11-17 19:01:07 -08001606TEST_F(ManagerTest, AvailableTechnologies) {
1607 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1608 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001609 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001610 manager(),
1611 "null4",
1612 "addr4",
1613 0));
1614 manager()->RegisterDevice(mock_devices_[0]);
1615 manager()->RegisterDevice(mock_devices_[1]);
1616 manager()->RegisterDevice(mock_devices_[2]);
1617 manager()->RegisterDevice(mock_devices_[3]);
1618
1619 ON_CALL(*mock_devices_[0].get(), technology())
1620 .WillByDefault(Return(Technology::kEthernet));
1621 ON_CALL(*mock_devices_[1].get(), technology())
1622 .WillByDefault(Return(Technology::kWifi));
1623 ON_CALL(*mock_devices_[2].get(), technology())
1624 .WillByDefault(Return(Technology::kCellular));
1625 ON_CALL(*mock_devices_[3].get(), technology())
1626 .WillByDefault(Return(Technology::kWifi));
1627
1628 set<string> expected_technologies;
1629 expected_technologies.insert(Technology::NameFromIdentifier(
1630 Technology::kEthernet));
1631 expected_technologies.insert(Technology::NameFromIdentifier(
1632 Technology::kWifi));
1633 expected_technologies.insert(Technology::NameFromIdentifier(
1634 Technology::kCellular));
1635 Error error;
1636 vector<string> technologies = manager()->AvailableTechnologies(&error);
1637
1638 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1639 ContainerEq(expected_technologies));
1640}
1641
1642TEST_F(ManagerTest, ConnectedTechnologies) {
1643 scoped_refptr<MockService> connected_service1(
1644 new NiceMock<MockService>(control_interface(),
1645 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001646 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001647 manager()));
1648 scoped_refptr<MockService> connected_service2(
1649 new NiceMock<MockService>(control_interface(),
1650 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001651 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001652 manager()));
1653 scoped_refptr<MockService> disconnected_service1(
1654 new NiceMock<MockService>(control_interface(),
1655 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001656 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001657 manager()));
1658 scoped_refptr<MockService> disconnected_service2(
1659 new NiceMock<MockService>(control_interface(),
1660 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001661 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001662 manager()));
1663
1664 ON_CALL(*connected_service1.get(), IsConnected())
1665 .WillByDefault(Return(true));
1666 ON_CALL(*connected_service2.get(), IsConnected())
1667 .WillByDefault(Return(true));
1668
1669 manager()->RegisterService(connected_service1);
1670 manager()->RegisterService(connected_service2);
1671 manager()->RegisterService(disconnected_service1);
1672 manager()->RegisterService(disconnected_service2);
1673
1674 manager()->RegisterDevice(mock_devices_[0]);
1675 manager()->RegisterDevice(mock_devices_[1]);
1676 manager()->RegisterDevice(mock_devices_[2]);
1677 manager()->RegisterDevice(mock_devices_[3]);
1678
1679 ON_CALL(*mock_devices_[0].get(), technology())
1680 .WillByDefault(Return(Technology::kEthernet));
1681 ON_CALL(*mock_devices_[1].get(), technology())
1682 .WillByDefault(Return(Technology::kWifi));
1683 ON_CALL(*mock_devices_[2].get(), technology())
1684 .WillByDefault(Return(Technology::kCellular));
1685 ON_CALL(*mock_devices_[3].get(), technology())
1686 .WillByDefault(Return(Technology::kWifi));
1687
1688 mock_devices_[0]->SelectService(connected_service1);
1689 mock_devices_[1]->SelectService(disconnected_service1);
1690 mock_devices_[2]->SelectService(disconnected_service2);
1691 mock_devices_[3]->SelectService(connected_service2);
1692
1693 set<string> expected_technologies;
1694 expected_technologies.insert(Technology::NameFromIdentifier(
1695 Technology::kEthernet));
1696 expected_technologies.insert(Technology::NameFromIdentifier(
1697 Technology::kWifi));
1698 Error error;
1699
1700 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1701 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1702 ContainerEq(expected_technologies));
1703}
1704
1705TEST_F(ManagerTest, DefaultTechnology) {
1706 scoped_refptr<MockService> connected_service(
1707 new NiceMock<MockService>(control_interface(),
1708 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001709 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001710 manager()));
1711 scoped_refptr<MockService> disconnected_service(
1712 new NiceMock<MockService>(control_interface(),
1713 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001714 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001715 manager()));
1716
1717 // Connected. WiFi.
1718 ON_CALL(*connected_service.get(), IsConnected())
1719 .WillByDefault(Return(true));
1720 ON_CALL(*connected_service.get(), state())
1721 .WillByDefault(Return(Service::kStateConnected));
1722 ON_CALL(*connected_service.get(), technology())
1723 .WillByDefault(Return(Technology::kWifi));
1724
1725 // Disconnected. Ethernet.
1726 ON_CALL(*disconnected_service.get(), technology())
1727 .WillByDefault(Return(Technology::kEthernet));
1728
1729 manager()->RegisterService(disconnected_service);
1730 Error error;
1731 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1732
1733
1734 manager()->RegisterService(connected_service);
1735 // Connected service should be brought to the front now.
1736 string expected_technology =
1737 Technology::NameFromIdentifier(Technology::kWifi);
1738 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1739}
1740
Thieu Le1271d682011-11-02 22:48:19 +00001741TEST_F(ManagerTest, DisconnectServicesOnStop) {
1742 scoped_refptr<MockService> mock_service(
1743 new NiceMock<MockService>(control_interface(),
1744 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001745 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001746 manager()));
1747 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001748 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001749 manager()->Stop();
1750}
1751
mukesh agrawal00917ce2011-11-22 23:56:55 +00001752TEST_F(ManagerTest, UpdateServiceConnected) {
1753 scoped_refptr<MockService> mock_service(
1754 new NiceMock<MockService>(control_interface(),
1755 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001756 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001757 manager()));
1758 manager()->RegisterService(mock_service);
1759 EXPECT_FALSE(mock_service->favorite());
1760 EXPECT_FALSE(mock_service->auto_connect());
1761
Gaurav Shah435de2c2011-11-17 19:01:07 -08001762 EXPECT_CALL(*mock_service.get(), IsConnected())
1763 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001764 manager()->UpdateService(mock_service);
1765 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1766 // to mock out MakeFavorite. And mocking that out would break the
1767 // SortServices test. (crosbug.com/23370)
1768 EXPECT_TRUE(mock_service->favorite());
1769 EXPECT_TRUE(mock_service->auto_connect());
1770}
1771
Thieu Led4e9e552012-02-16 16:26:07 -08001772TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1773 // This tests the case where the user connects to a service that is
1774 // currently associated with a profile. We want to make sure that the
1775 // favorite flag is set and that the flag is saved to the current
1776 // profile.
1777 scoped_refptr<MockService> mock_service(
1778 new NiceMock<MockService>(control_interface(),
1779 dispatcher(),
1780 metrics(),
1781 manager()));
1782 manager()->RegisterService(mock_service);
1783 EXPECT_FALSE(mock_service->favorite());
1784 EXPECT_FALSE(mock_service->auto_connect());
1785
Gary Moraind93615e2012-04-27 11:50:03 -07001786 scoped_refptr<MockProfile> profile(
1787 new MockProfile(control_interface(), manager(), ""));
Thieu Led4e9e552012-02-16 16:26:07 -08001788
Gary Moraind93615e2012-04-27 11:50:03 -07001789 mock_service->set_profile(profile);
1790 EXPECT_CALL(*mock_service, IsConnected())
Thieu Led4e9e552012-02-16 16:26:07 -08001791 .WillRepeatedly(Return(true));
Gary Moraind93615e2012-04-27 11:50:03 -07001792 EXPECT_CALL(*profile,
1793 UpdateService(static_cast<ServiceRefPtr>(mock_service)));
Thieu Led4e9e552012-02-16 16:26:07 -08001794 manager()->UpdateService(mock_service);
1795 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1796 // to mock out MakeFavorite. And mocking that out would break the
1797 // SortServices test. (crosbug.com/23370)
1798 EXPECT_TRUE(mock_service->favorite());
1799 EXPECT_TRUE(mock_service->auto_connect());
Gary Moraind93615e2012-04-27 11:50:03 -07001800 // This releases the ref on the mock profile.
1801 mock_service->set_profile(NULL);
Thieu Led4e9e552012-02-16 16:26:07 -08001802}
1803
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001804TEST_F(ManagerTest, SaveSuccessfulService) {
1805 scoped_refptr<MockProfile> profile(
1806 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1807 AdoptProfile(manager(), profile);
1808 scoped_refptr<MockService> service(
1809 new NiceMock<MockService>(control_interface(),
1810 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001811 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001812 manager()));
1813
1814 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1815 ServiceRefPtr expect_service(service.get());
1816
1817 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1818 .WillOnce(Return(false));
1819 manager()->RegisterService(service);
1820
1821 EXPECT_CALL(*service.get(), state())
1822 .WillRepeatedly(Return(Service::kStateConnected));
1823 EXPECT_CALL(*service.get(), IsConnected())
1824 .WillRepeatedly(Return(true));
1825 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1826 .WillOnce(Return(true));
1827 manager()->UpdateService(service);
1828}
1829
Paul Stewart1b253142012-01-26 14:05:52 -08001830TEST_F(ManagerTest, EnumerateProfiles) {
1831 vector<string> profile_paths;
1832 for (size_t i = 0; i < 10; i++) {
1833 scoped_refptr<MockProfile> profile(
1834 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001835 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001836 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1837 .WillOnce(Return(profile_paths.back()));
1838 AdoptProfile(manager(), profile);
1839 }
1840
1841 Error error;
1842 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1843 EXPECT_TRUE(error.IsSuccess());
1844 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1845 for (size_t i = 0; i < profile_paths.size(); i++) {
1846 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1847 }
1848}
1849
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001850TEST_F(ManagerTest, AutoConnectOnRegister) {
1851 MockServiceRefPtr service = MakeAutoConnectableService();
1852 EXPECT_CALL(*service.get(), AutoConnect());
1853 manager()->RegisterService(service);
1854 dispatcher()->DispatchPendingEvents();
1855}
1856
1857TEST_F(ManagerTest, AutoConnectOnUpdate) {
1858 MockServiceRefPtr service1 = MakeAutoConnectableService();
1859 service1->set_priority(1);
1860 MockServiceRefPtr service2 = MakeAutoConnectableService();
1861 service2->set_priority(2);
1862 manager()->RegisterService(service1);
1863 manager()->RegisterService(service2);
1864 dispatcher()->DispatchPendingEvents();
1865
1866 EXPECT_CALL(*service1.get(), AutoConnect());
1867 EXPECT_CALL(*service2.get(), state())
1868 .WillRepeatedly(Return(Service::kStateFailure));
1869 EXPECT_CALL(*service2.get(), IsFailed())
1870 .WillRepeatedly(Return(true));
1871 EXPECT_CALL(*service2.get(), IsConnected())
1872 .WillRepeatedly(Return(false));
1873 manager()->UpdateService(service2);
1874 dispatcher()->DispatchPendingEvents();
1875}
1876
1877TEST_F(ManagerTest, AutoConnectOnDeregister) {
1878 MockServiceRefPtr service1 = MakeAutoConnectableService();
1879 service1->set_priority(1);
1880 MockServiceRefPtr service2 = MakeAutoConnectableService();
1881 service2->set_priority(2);
1882 manager()->RegisterService(service1);
1883 manager()->RegisterService(service2);
1884 dispatcher()->DispatchPendingEvents();
1885
1886 EXPECT_CALL(*service1.get(), AutoConnect());
1887 manager()->DeregisterService(service2);
1888 dispatcher()->DispatchPendingEvents();
1889}
1890
Paul Stewartc681fa02012-03-02 19:40:04 -08001891TEST_F(ManagerTest, RecheckPortal) {
1892 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1893 .WillOnce(Return(false));
1894 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1895 .WillOnce(Return(true));
1896 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1897 .Times(0);
1898
1899 manager()->RegisterDevice(mock_devices_[0]);
1900 manager()->RegisterDevice(mock_devices_[1]);
1901 manager()->RegisterDevice(mock_devices_[2]);
1902
1903 manager()->RecheckPortal(NULL);
1904}
1905
Paul Stewartd215af62012-04-24 23:25:50 -07001906TEST_F(ManagerTest, RecheckPortalOnService) {
1907 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
1908 dispatcher(),
1909 metrics(),
1910 manager());
1911 EXPECT_CALL(*mock_devices_[0].get(),
1912 IsConnectedToService(IsRefPtrTo(service)))
1913 .WillOnce(Return(false));
1914 EXPECT_CALL(*mock_devices_[1].get(),
1915 IsConnectedToService(IsRefPtrTo(service)))
1916 .WillOnce(Return(true));
1917 EXPECT_CALL(*mock_devices_[1].get(), RestartPortalDetection())
1918 .WillOnce(Return(true));
1919 EXPECT_CALL(*mock_devices_[2].get(), IsConnectedToService(_))
1920 .Times(0);
1921
1922 manager()->RegisterDevice(mock_devices_[0]);
1923 manager()->RegisterDevice(mock_devices_[1]);
1924 manager()->RegisterDevice(mock_devices_[2]);
1925
1926 manager()->RecheckPortalOnService(service);
1927}
1928
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001929TEST_F(ManagerTest, GetDefaultService) {
1930 EXPECT_FALSE(manager()->GetDefaultService().get());
1931
1932 scoped_refptr<MockService> mock_service(
1933 new NiceMock<MockService>(control_interface(),
1934 dispatcher(),
1935 metrics(),
1936 manager()));
1937
1938 manager()->RegisterService(mock_service);
1939 EXPECT_FALSE(manager()->GetDefaultService().get());
1940
1941 scoped_refptr<MockConnection> mock_connection(
1942 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001943 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001944 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1945
Paul Stewartce4ec192012-03-14 12:53:46 -07001946 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001947 manager()->DeregisterService(mock_service);
1948}
1949
Paul Stewart13ed2252012-03-21 12:52:46 -07001950TEST_F(ManagerTest, GetServiceWithGUID) {
1951 scoped_refptr<MockService> mock_service0(
1952 new NiceMock<MockService>(control_interface(),
1953 dispatcher(),
1954 metrics(),
1955 manager()));
1956
1957 scoped_refptr<MockService> mock_service1(
1958 new NiceMock<MockService>(control_interface(),
1959 dispatcher(),
1960 metrics(),
1961 manager()));
1962
Paul Stewartcb59fed2012-03-21 21:14:46 -07001963 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1964 .Times(0);
1965 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1966 .Times(0);
1967
Paul Stewart13ed2252012-03-21 12:52:46 -07001968 manager()->RegisterService(mock_service0);
1969 manager()->RegisterService(mock_service1);
1970
1971 const string kGUID0 = "GUID0";
1972 const string kGUID1 = "GUID1";
1973
1974 {
1975 Error error;
1976 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1977 EXPECT_FALSE(error.IsSuccess());
1978 EXPECT_FALSE(service);
1979 }
1980
1981 KeyValueStore args;
1982 args.SetString(flimflam::kGuidProperty, kGUID1);
1983
1984 {
1985 Error error;
1986 ServiceRefPtr service = manager()->GetService(args, &error);
1987 EXPECT_EQ(Error::kInvalidArguments, error.type());
1988 EXPECT_FALSE(service);
1989 }
1990
1991 mock_service0->set_guid(kGUID0);
1992 mock_service1->set_guid(kGUID1);
1993
1994 {
1995 Error error;
1996 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1997 EXPECT_TRUE(error.IsSuccess());
1998 EXPECT_EQ(mock_service0.get(), service.get());
1999 }
2000
2001 {
2002 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07002003 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
2004 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07002005 ServiceRefPtr service = manager()->GetService(args, &error);
2006 EXPECT_TRUE(error.IsSuccess());
2007 EXPECT_EQ(mock_service1.get(), service.get());
2008 }
2009
2010 manager()->DeregisterService(mock_service0);
2011 manager()->DeregisterService(mock_service1);
2012}
2013
Gary Morain028545d2012-04-07 14:55:52 -07002014
2015TEST_F(ManagerTest, CalculateStateOffline) {
2016 MockMetrics mock_metrics;
2017 manager()->set_metrics(&mock_metrics);
2018 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2019 .Times(AnyNumber());
2020 scoped_refptr<MockService> mock_service0(
2021 new NiceMock<MockService>(control_interface(),
2022 dispatcher(),
2023 metrics(),
2024 manager()));
2025
2026 scoped_refptr<MockService> mock_service1(
2027 new NiceMock<MockService>(control_interface(),
2028 dispatcher(),
2029 metrics(),
2030 manager()));
2031
2032 EXPECT_CALL(*mock_service0.get(), IsConnected())
2033 .WillRepeatedly(Return(false));
2034 EXPECT_CALL(*mock_service1.get(), IsConnected())
2035 .WillRepeatedly(Return(false));
2036
2037 manager()->RegisterService(mock_service0);
2038 manager()->RegisterService(mock_service1);
2039
2040 EXPECT_EQ("offline", manager()->CalculateState(NULL));
2041
2042 manager()->DeregisterService(mock_service0);
2043 manager()->DeregisterService(mock_service1);
2044}
2045
2046TEST_F(ManagerTest, CalculateStateOnline) {
2047 MockMetrics mock_metrics;
2048 manager()->set_metrics(&mock_metrics);
2049 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(_))
2050 .Times(AnyNumber());
2051 scoped_refptr<MockService> mock_service0(
2052 new NiceMock<MockService>(control_interface(),
2053 dispatcher(),
2054 metrics(),
2055 manager()));
2056
2057 scoped_refptr<MockService> mock_service1(
2058 new NiceMock<MockService>(control_interface(),
2059 dispatcher(),
2060 metrics(),
2061 manager()));
2062
2063 EXPECT_CALL(*mock_service0.get(), IsConnected())
2064 .WillRepeatedly(Return(false));
2065 EXPECT_CALL(*mock_service1.get(), IsConnected())
2066 .WillRepeatedly(Return(true));
2067 EXPECT_CALL(*mock_service0.get(), state())
2068 .WillRepeatedly(Return(Service::kStateIdle));
2069 EXPECT_CALL(*mock_service1.get(), state())
2070 .WillRepeatedly(Return(Service::kStateConnected));
2071
2072 manager()->RegisterService(mock_service0);
2073 manager()->RegisterService(mock_service1);
2074
2075 EXPECT_EQ("online", manager()->CalculateState(NULL));
2076
2077 manager()->DeregisterService(mock_service0);
2078 manager()->DeregisterService(mock_service1);
2079}
2080
Paul Stewart10e9e4e2012-04-26 19:46:28 -07002081TEST_F(ManagerTest, StartupPortalList) {
2082 // Simulate loading value from the default profile.
2083 const string kProfileValue("wifi,vpn");
2084 manager()->props_.check_portal_list = kProfileValue;
2085
2086 EXPECT_EQ(kProfileValue, manager()->GetCheckPortalList(NULL));
2087 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2088 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2089
2090 const string kStartupValue("cellular,ethernet");
2091 manager()->SetStartupPortalList(kStartupValue);
2092 // Ensure profile value is not overwritten, so when we save the default
2093 // profile, the correct value will still be written.
2094 EXPECT_EQ(kProfileValue, manager()->props_.check_portal_list);
2095
2096 // However we should read back a different list.
2097 EXPECT_EQ(kStartupValue, manager()->GetCheckPortalList(NULL));
2098 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kWifi));
2099 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2100
2101 const string kRuntimeValue("ppp");
2102 // Setting a runtime value over the control API should overwrite both
2103 // the profile value and what we read back.
2104 Error error;
2105 manager()->mutable_store()->SetStringProperty(
2106 flimflam::kCheckPortalListProperty,
2107 kRuntimeValue,
2108 &error);
2109 ASSERT_TRUE(error.IsSuccess());
2110 EXPECT_EQ(kRuntimeValue, manager()->GetCheckPortalList(NULL));
2111 EXPECT_EQ(kRuntimeValue, manager()->props_.check_portal_list);
2112 EXPECT_FALSE(manager()->IsPortalDetectionEnabled(Technology::kCellular));
2113 EXPECT_TRUE(manager()->IsPortalDetectionEnabled(Technology::kPPP));
2114}
2115
Jason Glasgowdf7c5532012-05-14 14:41:45 -04002116TEST_F(ManagerTest, EnableTechnology) {
2117 Error error(Error::kOperationInitiated);
2118 ResultCallback callback;
2119 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2120 EXPECT_TRUE(error.IsSuccess());
2121
2122 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2123 .WillByDefault(Return(true));
2124
2125 manager()->RegisterDevice(mock_devices_[0]);
2126
2127 // Device is enabled, so expect operation is successful.
2128 mock_devices_[0]->enabled_ = true;
2129 error.Populate(Error::kOperationInitiated);
2130 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2131 EXPECT_TRUE(error.IsSuccess());
2132
2133 // Device is disabled, so expect operation in progress.
2134 mock_devices_[0]->enabled_ = false;
2135 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(true, _, _));
2136 error.Populate(Error::kOperationInitiated);
2137 manager()->EnableTechnology(flimflam::kTypeEthernet, &error, callback);
2138 EXPECT_TRUE(error.IsOngoing());
2139}
2140
2141TEST_F(ManagerTest, DisableTechnology) {
2142 Error error(Error::kOperationInitiated);
2143 ResultCallback callback;
2144 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2145 EXPECT_TRUE(error.IsSuccess());
2146
2147 ON_CALL(*mock_devices_[0], TechnologyIs(Technology::kEthernet))
2148 .WillByDefault(Return(true));
2149
2150 manager()->RegisterDevice(mock_devices_[0]);
2151
2152 // Device is disabled, so expect operation is successful.
2153 error.Populate(Error::kOperationInitiated);
2154 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2155 EXPECT_TRUE(error.IsSuccess());
2156
2157 // Device is enabled, so expect operation in progress.
2158 EXPECT_CALL(*mock_devices_[0], SetEnabledPersistent(false, _, _));
2159 mock_devices_[0]->enabled_ = true;
2160 error.Populate(Error::kOperationInitiated);
2161 manager()->DisableTechnology(flimflam::kTypeEthernet, &error, callback);
2162 EXPECT_TRUE(error.IsOngoing());
2163}
2164
2165
Chris Masone9be4a9d2011-05-16 15:44:09 -07002166} // namespace shill