blob: c7b05f04f02752176404b2a62a186b1dd3f0cc1a [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone9be4a9d2011-05-16 15:44:09 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07004
5#include "shill/manager.h"
6
Chris Masone6791a432011-07-12 13:23:19 -07007#include <set>
8
Chris Masone9be4a9d2011-05-16 15:44:09 -07009#include <glib.h>
10
Chris Masone9be4a9d2011-05-16 15:44:09 -070011#include <base/logging.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050012#include <base/scoped_temp_dir.h>
13#include <base/stl_util.h>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070014#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <chromeos/dbus/service_constants.h>
Chris Masone7156c922011-08-23 20:36:21 -070016#include <gmock/gmock.h>
Chris Masone2ae797d2011-08-23 20:41:00 -070017#include <gtest/gtest.h>
Chris Masone9be4a9d2011-05-16 15:44:09 -070018
mukesh agrawal32399322011-09-01 10:53:43 -070019#include "shill/adaptor_interfaces.h"
Chris Masone6515aab2011-10-12 16:19:09 -070020#include "shill/ephemeral_profile.h"
mukesh agrawal32399322011-09-01 10:53:43 -070021#include "shill/error.h"
Chris Masone6515aab2011-10-12 16:19:09 -070022#include "shill/glib.h"
23#include "shill/key_file_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070024#include "shill/key_value_store.h"
mukesh agrawal32399322011-09-01 10:53:43 -070025#include "shill/mock_adaptors.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080026#include "shill/mock_connection.h"
Chris Masoned7732e42011-05-20 11:08:56 -070027#include "shill/mock_control.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070028#include "shill/mock_device.h"
Paul Stewartc1dec4d2011-12-08 15:25:28 -080029#include "shill/mock_device_info.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070030#include "shill/mock_glib.h"
Thieu Lea20cbc22012-01-09 22:01:43 +000031#include "shill/mock_metrics.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070032#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070033#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070034#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070035#include "shill/mock_wifi.h"
Paul Stewart7f61e522012-03-22 11:13:45 -070036#include "shill/mock_wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070037#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070038#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070039#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070040
41using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070042using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070043using std::string;
44using std::vector;
45
Chris Masone9be4a9d2011-05-16 15:44:09 -070046namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070047using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070048using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080049using ::testing::ContainerEq;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070050using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070051using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070052using ::testing::NiceMock;
53using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070054using ::testing::ReturnRef;
Gaurav Shah435de2c2011-11-17 19:01:07 -080055using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080056using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070057using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070058
Chris Masone3bd3c8c2011-06-13 08:20:26 -070059class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070060 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070061 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070062 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070063 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080064 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070065 manager(),
66 "wifi0",
67 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080068 4)),
69 device_info_(new NiceMock<MockDeviceInfo>(
70 control_interface(),
71 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080072 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080073 reinterpret_cast<Manager*>(NULL))),
74 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070075 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
76 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080077 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070078 manager(),
79 "null0",
80 "addr0",
81 0));
82 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
83 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080084 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070085 manager(),
86 "null1",
87 "addr1",
88 1));
89 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
90 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080091 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070092 manager(),
93 "null2",
94 "addr2",
95 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080096 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
97 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080098 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -080099 manager(),
100 "null3",
101 "addr3",
102 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700103 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800104
105 // Replace the manager's adaptor with a quieter one, and one
106 // we can do EXPECT*() against. Passes ownership.
107 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700108 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700109 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700110
Paul Stewartfdd16072011-09-16 12:41:35 -0700111 bool IsDeviceRegistered(const DeviceRefPtr &device,
112 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700113 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700114 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700115 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700116 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700117 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700118
Paul Stewarta849a3d2011-11-03 05:54:09 -0700119 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
120 manager->profiles_.push_back(profile);
121 }
122
Paul Stewart75225512012-01-26 22:51:33 -0800123 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
124 return manager->ephemeral_profile_;
125 }
126
Chris Masone6515aab2011-10-12 16:19:09 -0700127 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
128 Profile::Identifier id("rather", "irrelevant");
129 scoped_ptr<Profile> profile(new Profile(control_interface(),
130 manager,
131 id,
132 "",
133 false));
134 FilePath final_path(storage_path());
135 final_path = final_path.Append("test.profile");
136 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
137 storage->set_path(final_path);
138 if (!storage->Open())
139 return NULL;
140 profile->set_storage(storage.release()); // Passes ownership.
141 return profile.release();
142 }
143
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700144 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
145 const string &profile_identifier,
146 const string &service_name) {
147 GLib glib;
148 KeyFileStore store(&glib);
149 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
150 return store.Open() &&
151 store.SetString(service_name, "rather", "irrelevant") &&
152 store.Close();
153 }
154
155 Error::Type TestCreateProfile(Manager *manager, const string &name) {
156 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800157 string path;
158 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700159 return error.type();
160 }
161
162 Error::Type TestPopAnyProfile(Manager *manager) {
163 Error error;
164 manager->PopAnyProfile(&error);
165 return error.type();
166 }
167
168 Error::Type TestPopProfile(Manager *manager, const string &name) {
169 Error error;
170 manager->PopProfile(name, &error);
171 return error.type();
172 }
173
174 Error::Type TestPushProfile(Manager *manager, const string &name) {
175 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800176 string path;
177 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700178 return error.type();
179 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000180
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700181 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000182 typedef scoped_refptr<MockService> MockServiceRefPtr;
183
184 MockServiceRefPtr MakeAutoConnectableService() {
185 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
186 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800187 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000188 manager());
189 service->MakeFavorite();
190 service->set_connectable(true);
191 return service;
192 }
193
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700194 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700195 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800196 scoped_ptr<MockDeviceInfo> device_info_;
197
198 // This pointer is owned by the manager, and only tracked here for EXPECT*()
199 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700200};
201
Paul Stewart22aa71b2011-09-16 12:15:11 -0700202bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
203 return (svc0.get() == manager()->services_[0].get() &&
204 svc1.get() == manager()->services_[1].get());
205}
206
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700207TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700208 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
209 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700210}
211
Chris Masone9be4a9d2011-05-16 15:44:09 -0700212TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700213 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700214 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700215 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700216 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700217 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700218 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700219
Paul Stewart22aa71b2011-09-16 12:15:11 -0700220 manager()->RegisterDevice(mock_devices_[0]);
221 manager()->RegisterDevice(mock_devices_[1]);
222 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700223
Paul Stewart22aa71b2011-09-16 12:15:11 -0700224 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
225 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
226 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700227}
228
Paul Stewarta41e38d2011-11-11 07:47:29 -0800229TEST_F(ManagerTest, DeviceRegistrationAndStart) {
230 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500231 mock_devices_[0]->enabled_persistent_ = true;
232 mock_devices_[1]->enabled_persistent_ = false;
233 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800234 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500235 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800236 .Times(0);
237 manager()->RegisterDevice(mock_devices_[0]);
238 manager()->RegisterDevice(mock_devices_[1]);
239}
240
241TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
242 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
243 DeviceRefPtr device_ref(mock_devices_[0].get());
244 AdoptProfile(manager(), profile); // Passes ownership.
245 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
246 EXPECT_CALL(*profile, Save());
247 manager()->RegisterDevice(mock_devices_[0]);
248}
249
Chris Masone9be4a9d2011-05-16 15:44:09 -0700250TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700251 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700252 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700253 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700254 .WillByDefault(Return(true));
255
Gaurav Shah435de2c2011-11-17 19:01:07 -0800256 manager()->RegisterDevice(mock_devices_[0]);
257 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700258
Paul Stewart22aa71b2011-09-16 12:15:11 -0700259 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
260 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700261
Eric Shienbrood9a245532012-03-07 14:20:39 -0500262 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800263 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700264 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700265
Eric Shienbrood9a245532012-03-07 14:20:39 -0500266 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800267 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700268 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700269}
270
271TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700272 // It's much easier and safer to use a real GLib for this test.
273 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700274 Manager manager(control_interface(),
275 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800276 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700277 &glib,
278 run_path(),
279 storage_path(),
280 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700281 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
282 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700283 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700284
Chris Masone9be4a9d2011-05-16 15:44:09 -0700285 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700286 new NiceMock<MockService>(control_interface(),
287 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800288 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700289 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700290 scoped_refptr<MockService> mock_service2(
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));
Paul Stewartce4ec192012-03-14 12:53:46 -0700295
mukesh agrawal51a7e932011-07-27 16:18:26 -0700296 string service1_name(mock_service->UniqueName());
297 string service2_name(mock_service2->UniqueName());
298
299 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
300 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700301 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700302 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700303 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700304 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700305 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700306
Chris Masone9d779932011-08-25 16:33:41 -0700307 manager.RegisterService(mock_service);
308 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700309
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800310 Error error;
311 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700312 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700313 EXPECT_EQ(2, ids.size());
314 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
315 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700316
Chris Masone9d779932011-08-25 16:33:41 -0700317 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
318 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
319
320 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700321}
322
Chris Masone6515aab2011-10-12 16:19:09 -0700323TEST_F(ManagerTest, RegisterKnownService) {
324 // It's much easier and safer to use a real GLib for this test.
325 GLib glib;
326 Manager manager(control_interface(),
327 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800328 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700329 &glib,
330 run_path(),
331 storage_path(),
332 string());
333 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
334 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700335 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700336 {
337 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
338 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800339 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700340 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700341 ASSERT_TRUE(profile->AdoptService(service1));
342 ASSERT_TRUE(profile->ContainsService(service1));
343 } // Force destruction of service1.
344
345 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
346 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800347 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700348 &manager));
349 manager.RegisterService(service2);
350 EXPECT_EQ(service2->profile().get(), profile.get());
351 manager.Stop();
352}
353
354TEST_F(ManagerTest, RegisterUnknownService) {
355 // It's much easier and safer to use a real GLib for this test.
356 GLib glib;
357 Manager manager(control_interface(),
358 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800359 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700360 &glib,
361 run_path(),
362 storage_path(),
363 string());
364 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
365 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700366 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700367 {
368 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
369 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800370 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700371 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700372 ASSERT_TRUE(profile->AdoptService(service1));
373 ASSERT_TRUE(profile->ContainsService(service1));
374 } // Force destruction of service1.
375 scoped_refptr<MockService> mock_service2(
376 new NiceMock<MockService>(control_interface(),
377 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800378 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700379 &manager));
380 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
381 .WillRepeatedly(Return(mock_service2->UniqueName()));
382 manager.RegisterService(mock_service2);
383 EXPECT_NE(mock_service2->profile().get(), profile.get());
384 manager.Stop();
385}
386
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000387TEST_F(ManagerTest, DeregisterUnregisteredService) {
388 // WiFi assumes that it can deregister a service that is not
389 // registered. (E.g. a hidden service can be deregistered when it
390 // loses its last endpoint, and again when WiFi is Stop()-ed.)
391 //
392 // So test that doing so doesn't cause a crash.
393 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
394 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800395 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000396 manager());
397 manager()->DeregisterService(service);
398}
399
Chris Masonea8a2c252011-06-27 22:16:30 -0700400TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700401 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700402 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700403 map<string, ::DBus::Variant> props;
404 Error error(Error::kInvalidProperty, "");
405 {
406 ::DBus::Error dbus_error;
407 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700408 manager()->mutable_store()->SetStringProperty(
409 flimflam::kCheckPortalListProperty,
410 expected,
411 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700412 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700413 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
414 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
415 expected);
416 }
417 {
418 ::DBus::Error dbus_error;
419 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700420 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
421 expected,
422 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700423 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700424 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
425 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
426 expected);
427 }
428}
429
Chris Masone3c3f6a12011-07-01 10:01:41 -0700430TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700431 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700432 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800433 manager()->RegisterDevice(mock_devices_[0]);
434 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700435 {
436 map<string, ::DBus::Variant> props;
437 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700438 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700439 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
440 Strings devices =
441 props[flimflam::kDevicesProperty].operator vector<string>();
442 EXPECT_EQ(2, devices.size());
443 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700444}
445
mukesh agrawal2366eed2012-03-20 18:21:50 -0700446TEST_F(ManagerTest, GetServicesProperty) {
447 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
448 AdoptProfile(manager(), profile);
449 map<string, ::DBus::Variant> props;
450 ::DBus::Error dbus_error;
451 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
452 map<string, ::DBus::Variant>::const_iterator prop =
453 props.find(flimflam::kServicesProperty);
454 ASSERT_FALSE(prop == props.end());
455 const ::DBus::Variant &variant = prop->second;
456 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
457}
458
Chris Masone6791a432011-07-12 13:23:19 -0700459TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700460 Manager manager(control_interface(),
461 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800462 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700463 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700464 run_path(),
465 storage_path(),
466 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700467 scoped_refptr<MockService> s2(new MockService(control_interface(),
468 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800469 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700470 &manager));
471 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700472 {
Chris Masone6515aab2011-10-12 16:19:09 -0700473 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700474 ProfileRefPtr profile(
475 new Profile(control_interface(), &manager, id, "", false));
476 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700477 // Say we don't have |s2| the first time asked, then that we do.
478 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
479 .WillOnce(Return(false))
480 .WillRepeatedly(Return(true));
481 EXPECT_CALL(*storage, Flush())
482 .Times(AnyNumber())
483 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700484 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700485 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700486 }
Chris Masone6515aab2011-10-12 16:19:09 -0700487 // Create a profile that already has |s2| in it.
488 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
489 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700490
Chris Masone6515aab2011-10-12 16:19:09 -0700491 // Now, move the Service |s2| to another profile.
492 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
493 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700494
495 // Force destruction of the original Profile, to ensure that the Service
496 // is kept alive and populated with data.
497 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700498 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700499 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700500}
501
Paul Stewart7f61e522012-03-22 11:13:45 -0700502TEST_F(ManagerTest, LookupProfileByRpcIdentifier) {
503 scoped_refptr<MockProfile> mock_profile(
504 new MockProfile(control_interface(), manager(), ""));
505 const string kProfileName("profile0");
506 EXPECT_CALL(*mock_profile, GetRpcIdentifier())
507 .WillRepeatedly(Return(kProfileName));
508 AdoptProfile(manager(), mock_profile);
509
510 EXPECT_FALSE(manager()->LookupProfileByRpcIdentifier("foo"));
511 ProfileRefPtr profile = manager()->LookupProfileByRpcIdentifier(kProfileName);
512 EXPECT_EQ(mock_profile.get(), profile.get());
513}
514
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800515TEST_F(ManagerTest, SetProfileForService) {
516 scoped_refptr<MockProfile> profile0(
517 new MockProfile(control_interface(), manager(), ""));
518 string profile_name0("profile0");
519 EXPECT_CALL(*profile0, GetRpcIdentifier())
520 .WillRepeatedly(Return(profile_name0));
521 AdoptProfile(manager(), profile0);
522 scoped_refptr<MockService> service(new MockService(control_interface(),
523 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800524 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800525 manager()));
526 service->set_profile(profile0);
527
528 {
529 Error error;
530 manager()->SetProfileForService(service, "foo", &error);
531 EXPECT_EQ(Error::kInvalidArguments, error.type());
Paul Stewart7f61e522012-03-22 11:13:45 -0700532 EXPECT_EQ("Unknown Profile foo requested for Service", error.message());
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800533 }
534
535 {
536 Error error;
537 manager()->SetProfileForService(service, profile_name0, &error);
538 EXPECT_EQ(Error::kInvalidArguments, error.type());
539 EXPECT_EQ("Service is already connected to this profile", error.message());
540 }
541
542 scoped_refptr<MockProfile> profile1(
543 new MockProfile(control_interface(), manager(), ""));
544 string profile_name1("profile1");
545 EXPECT_CALL(*profile1, GetRpcIdentifier())
546 .WillRepeatedly(Return(profile_name1));
547 AdoptProfile(manager(), profile1);
548
549 {
550 Error error;
551 EXPECT_CALL(*profile1, AdoptService(_))
552 .WillOnce(Return(true));
553 EXPECT_CALL(*profile0, AbandonService(_))
554 .WillOnce(Return(true));
555 manager()->SetProfileForService(service, profile_name1, &error);
556 EXPECT_TRUE(error.IsSuccess());
557 }
558}
559
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700560TEST_F(ManagerTest, CreateProfile) {
561 // It's much easier to use real Glib here since we want the storage
562 // side-effects.
563 GLib glib;
564 ScopedTempDir temp_dir;
565 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
566
567 Manager manager(control_interface(),
568 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800569 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700570 &glib,
571 run_path(),
572 storage_path(),
573 temp_dir.path().value());
574
575 // Invalid name should be rejected.
576 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
577
578 // Valid name is still rejected because we can't create a profile
579 // that doesn't have a user component. Such profile names are
580 // reserved for the single DefaultProfile the manager creates
581 // at startup.
582 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, "valid"));
583
584 // We should succeed in creating a valid user profile.
585 const char kProfile[] = "~user/profile";
586 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
587
588 // We should fail in creating it a second time (already exists).
589 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
590}
591
592TEST_F(ManagerTest, PushPopProfile) {
593 // It's much easier to use real Glib in creating a Manager for this
594 // test here since we want the storage side-effects.
595 GLib glib;
596 ScopedTempDir temp_dir;
597 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
598 Manager manager(control_interface(),
599 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800600 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700601 &glib,
602 run_path(),
603 storage_path(),
604 temp_dir.path().value());
605
606 // Pushing an invalid profile should fail.
607 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
608
609 // Pushing a default profile name should fail.
610 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, "default"));
611
612 const char kProfile0[] = "~user/profile0";
613 const char kProfile1[] = "~user/profile1";
614
615 // Create a couple of profiles.
616 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
617 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
618
619 // Push these profiles on the stack.
620 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
621 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
622
623 // Pushing a profile a second time should fail.
624 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
625 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
626
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800627 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700628 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800629 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700630
631 // Make sure a profile name that doesn't exist fails.
632 const char kProfile2Id[] = "profile2";
633 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
634 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
635
636 // Create a new service, with a specific storage name.
637 scoped_refptr<MockService> service(
638 new NiceMock<MockService>(control_interface(),
639 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800640 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700641 &manager));
642 const char kServiceName[] = "service_storage_name";
643 EXPECT_CALL(*service.get(), GetStorageIdentifier())
644 .WillRepeatedly(Return(kServiceName));
645 EXPECT_CALL(*service.get(), Load(_))
646 .WillRepeatedly(Return(true));
647
648 // Add this service to the manager -- it should end up in the ephemeral
649 // profile.
650 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800651 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700652
653 // Create storage for a profile that contains the service storage name.
654 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
655 kServiceName));
656
657 // When we push the profile, the service should move away from the
658 // ephemeral profile to this new profile since it has an entry for
659 // this service.
660 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800661 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700662 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
663
664 // Insert another profile that should supersede ownership of the service.
665 const char kProfile3Id[] = "profile3";
666 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
667 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
668 kServiceName));
669 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
670 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
671
672 // Popping an invalid profile name should fail.
673 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
674
675 // Popping an profile that is not at the top of the stack should fail.
676 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
677
678 // Popping the top profile should succeed.
679 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
680
681 // Moreover the service should have switched profiles to profile 2.
682 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
683
684 // Popping the top profile should succeed.
685 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
686
687 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800688 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700689
690 // Pop the remaining two services off the stack.
691 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
692 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
693
694 // Next pop should fail with "stack is empty".
695 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
696}
697
Paul Stewart75225512012-01-26 22:51:33 -0800698// Use this matcher instead of passing RefPtrs directly into the arguments
699// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
700// system teardown.
701MATCHER_P(IsRefPtrTo, ref_address, "") {
702 return arg.get() == ref_address;
703}
704
705TEST_F(ManagerTest, HandleProfileEntryDeletion) {
706 MockServiceRefPtr s_not_in_profile(
707 new NiceMock<MockService>(control_interface(),
708 dispatcher(),
709 metrics(),
710 manager()));
711 MockServiceRefPtr s_not_in_group(
712 new NiceMock<MockService>(control_interface(),
713 dispatcher(),
714 metrics(),
715 manager()));
716 MockServiceRefPtr s_configure_fail(
717 new NiceMock<MockService>(control_interface(),
718 dispatcher(),
719 metrics(),
720 manager()));
721 MockServiceRefPtr s_configure_succeed(
722 new NiceMock<MockService>(control_interface(),
723 dispatcher(),
724 metrics(),
725 manager()));
726
727 string entry_name("entry_name");
728 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
729 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
730 .WillRepeatedly(Return("not_entry_name"));
731 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
732 .WillRepeatedly(Return(entry_name));
733 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
734 .WillRepeatedly(Return(entry_name));
735
736 manager()->RegisterService(s_not_in_profile);
737 manager()->RegisterService(s_not_in_group);
738 manager()->RegisterService(s_configure_fail);
739 manager()->RegisterService(s_configure_succeed);
740
741 scoped_refptr<MockProfile> profile0(
742 new StrictMock<MockProfile>(control_interface(), manager(), ""));
743 scoped_refptr<MockProfile> profile1(
744 new StrictMock<MockProfile>(control_interface(), manager(), ""));
745
746 s_not_in_group->set_profile(profile1);
747 s_configure_fail->set_profile(profile1);
748 s_configure_succeed->set_profile(profile1);
749
750 AdoptProfile(manager(), profile0);
751 AdoptProfile(manager(), profile1);
752
753 // No services are a member of this profile.
754 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
755
756 // No services that are members of this profile have this entry name.
757 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
758
759 // Only services that are members of the profile and group will be abandoned.
760 EXPECT_CALL(*profile1.get(),
761 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
762 EXPECT_CALL(*profile1.get(),
763 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
764 EXPECT_CALL(*profile1.get(),
765 AbandonService(IsRefPtrTo(s_configure_fail.get())))
766 .WillOnce(Return(true));
767 EXPECT_CALL(*profile1.get(),
768 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
769 .WillOnce(Return(true));
770
771 // Never allow services to re-join profile1.
772 EXPECT_CALL(*profile1.get(), ConfigureService(_))
773 .WillRepeatedly(Return(false));
774
775 // Only allow one of the members of the profile and group to successfully
776 // join profile0.
777 EXPECT_CALL(*profile0.get(),
778 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
779 EXPECT_CALL(*profile0.get(),
780 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
781 EXPECT_CALL(*profile0.get(),
782 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
783 .WillOnce(Return(false));
784 EXPECT_CALL(*profile0.get(),
785 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
786 .WillOnce(Return(true));
787
788 // Expect the failed-to-configure service to have Unload() called on it.
789 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
790 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
791 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
792 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
793
794 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
795
796 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
797 EXPECT_EQ(profile1, s_not_in_group->profile());
798 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
799
800 // Since we are using a MockProfile, the profile does not actually change,
801 // since ConfigureService was not actually called on the service.
802 EXPECT_EQ(profile1, s_configure_succeed->profile());
803}
804
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800805TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700806 {
807 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800808 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
809 flimflam::kOfflineModeProperty,
810 PropertyStoreTest::kBoolV,
811 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700812 }
813 {
814 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800815 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
816 flimflam::kCountryProperty,
817 PropertyStoreTest::kStringV,
818 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700819 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700820 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700821 {
822 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800823 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
824 flimflam::kCountryProperty,
825 PropertyStoreTest::kBoolV,
826 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700827 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700828 }
829 {
830 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800831 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
832 flimflam::kOfflineModeProperty,
833 PropertyStoreTest::kStringV,
834 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700835 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700836 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700837 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700838 {
839 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800840 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700841 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700842 flimflam::kEnabledTechnologiesProperty,
843 PropertyStoreTest::kStringsV,
844 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700845 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700846 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700847}
848
mukesh agrawal32399322011-09-01 10:53:43 -0700849TEST_F(ManagerTest, RequestScan) {
850 {
851 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700852 manager()->RegisterDevice(mock_devices_[0].get());
853 manager()->RegisterDevice(mock_devices_[1].get());
854 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700855 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700856 EXPECT_CALL(*mock_devices_[0], Scan(_));
857 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700858 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700859 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -0700860 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700861 }
862
863 {
864 Error error;
Chris Masone9d779932011-08-25 16:33:41 -0700865 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700866 EXPECT_EQ(Error::kInvalidArguments, error.type());
867 }
868}
869
Darin Petkovb65c2452012-02-23 15:17:06 +0100870TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700871 KeyValueStore args;
872 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100873 manager()->GetService(args, &e);
874 EXPECT_EQ(Error::kInvalidArguments, e.type());
875 EXPECT_EQ("must specify service type", e.message());
876}
877
878TEST_F(ManagerTest, GetServiceUnknownType) {
879 KeyValueStore args;
880 Error e;
881 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
882 manager()->GetService(args, &e);
883 EXPECT_EQ(Error::kNotSupported, e.type());
884 EXPECT_EQ("service type is unsupported", e.message());
885}
886
887TEST_F(ManagerTest, GetServiceNoWifiDevice) {
888 KeyValueStore args;
889 Error e;
890 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
891 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700892 EXPECT_EQ(Error::kInvalidArguments, e.type());
893 EXPECT_EQ("no wifi devices available", e.message());
894}
895
Darin Petkovb65c2452012-02-23 15:17:06 +0100896TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700897 KeyValueStore args;
898 Error e;
899 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +0100900 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700901 manager()->RegisterDevice(mock_wifi_);
902 EXPECT_CALL(*mock_wifi_, GetService(_, _))
903 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +0100904 manager()->GetService(args, &e);
905 EXPECT_TRUE(e.IsSuccess());
906}
907
Darin Petkov33af05c2012-02-28 10:10:30 +0100908TEST_F(ManagerTest, GetServiceVPNUnknownType) {
909 KeyValueStore args;
910 Error e;
911 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
912 ServiceRefPtr service = manager()->GetService(args, &e);
913 EXPECT_EQ(Error::kNotSupported, e.type());
914 EXPECT_FALSE(service);
915}
916
Darin Petkovb65c2452012-02-23 15:17:06 +0100917TEST_F(ManagerTest, GetServiceVPN) {
918 KeyValueStore args;
919 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100920 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +0100921 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +0100922 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
923 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +0100924 ServiceRefPtr service = manager()->GetService(args, &e);
925 EXPECT_TRUE(e.IsSuccess());
926 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700927}
928
Paul Stewart7f61e522012-03-22 11:13:45 -0700929TEST_F(ManagerTest, ConfigureServiceWithInvalidProfile) {
930 // Manager calls ActiveProfile() so we need at least one profile installed.
931 scoped_refptr<MockProfile> profile(
932 new NiceMock<MockProfile>(control_interface(), manager(), ""));
933 AdoptProfile(manager(), profile);
934
935 KeyValueStore args;
936 args.SetString(flimflam::kProfileProperty, "xxx");
937 Error error;
938 manager()->ConfigureService(args, &error);
939 EXPECT_EQ(Error::kInvalidArguments, error.type());
940 EXPECT_EQ("Invalid profile name xxx", error.message());
941}
942
943TEST_F(ManagerTest, ConfigureServiceWithGetServiceFailure) {
944 // Manager calls ActiveProfile() so we need at least one profile installed.
945 scoped_refptr<MockProfile> profile(
946 new NiceMock<MockProfile>(control_interface(), manager(), ""));
947 AdoptProfile(manager(), profile);
948
949 KeyValueStore args;
950 Error error;
951 manager()->ConfigureService(args, &error);
952 EXPECT_EQ(Error::kInvalidArguments, error.type());
953 EXPECT_EQ("must specify service type", error.message());
954}
955
956// A registered service in the ephemeral profile should be moved to the
957// active profile as a part of configuration if no profile was explicitly
958// specified.
959TEST_F(ManagerTest, ConfigureRegisteredServiceWithoutProfile) {
960 scoped_refptr<MockProfile> profile(
961 new NiceMock<MockProfile>(control_interface(), manager(), ""));
962
963 AdoptProfile(manager(), profile); // This is now the active profile.
964
965 const std::vector<uint8_t> ssid;
966 scoped_refptr<MockWiFiService> service(
967 new NiceMock<MockWiFiService>(control_interface(),
968 dispatcher(),
969 metrics(),
970 manager(),
971 mock_wifi_,
972 ssid,
973 "",
974 "",
975 false));
976
977 manager()->RegisterService(service);
978 service->set_profile(GetEphemeralProfile(manager()));
979
980 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
981 // the same device as that used above causes a refcounting loop.
982 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
983 dispatcher(),
984 metrics(),
985 manager(),
986 "wifi1",
987 "addr5",
988 5));
989 manager()->RegisterDevice(wifi);
990 EXPECT_CALL(*wifi, GetService(_, _))
991 .WillOnce(Return(service));
992 EXPECT_CALL(*profile, UpdateService(ServiceRefPtr(service.get())))
993 .WillOnce(Return(true));
994 EXPECT_CALL(*profile, AdoptService(ServiceRefPtr(service.get())))
995 .WillOnce(Return(true));
996
997 KeyValueStore args;
998 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
999 Error error;
1000 manager()->ConfigureService(args, &error);
1001 EXPECT_TRUE(error.IsSuccess());
1002}
1003
1004// If were configure a service that was already registered and explicitly
1005// specify a profile, it should be moved from the profile it was previously
1006// in to the specified profile if one was requested.
1007TEST_F(ManagerTest, ConfigureRegisteredServiceWithProfile) {
1008 scoped_refptr<MockProfile> profile0(
1009 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1010 scoped_refptr<MockProfile> profile1(
1011 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1012
1013 const string kProfileName0 = "profile0";
1014 const string kProfileName1 = "profile1";
1015
1016 EXPECT_CALL(*profile0, GetRpcIdentifier())
1017 .WillRepeatedly(Return(kProfileName0));
1018 EXPECT_CALL(*profile1, GetRpcIdentifier())
1019 .WillRepeatedly(Return(kProfileName1));
1020
1021 AdoptProfile(manager(), profile0);
1022 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1023
1024 const std::vector<uint8_t> ssid;
1025 scoped_refptr<MockWiFiService> service(
1026 new NiceMock<MockWiFiService>(control_interface(),
1027 dispatcher(),
1028 metrics(),
1029 manager(),
1030 mock_wifi_,
1031 ssid,
1032 "",
1033 "",
1034 false));
1035
1036 manager()->RegisterService(service);
1037 service->set_profile(profile1);
1038
1039 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1040 // the same device as that used above causes a refcounting loop.
1041 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1042 dispatcher(),
1043 metrics(),
1044 manager(),
1045 "wifi1",
1046 "addr5",
1047 5));
1048 manager()->RegisterDevice(wifi);
1049 EXPECT_CALL(*wifi, GetService(_, _))
1050 .WillOnce(Return(service));
1051 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1052 .WillOnce(Return(true));
1053 EXPECT_CALL(*profile0, AdoptService(ServiceRefPtr(service.get())))
1054 .WillOnce(Return(true));
1055 EXPECT_CALL(*profile1, AbandonService(ServiceRefPtr(service.get())))
1056 .WillOnce(Return(true));
1057
1058 KeyValueStore args;
1059 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1060 args.SetString(flimflam::kProfileProperty, kProfileName0);
1061 Error error;
1062 manager()->ConfigureService(args, &error);
1063 EXPECT_TRUE(error.IsSuccess());
1064 service->set_profile(NULL); // Breaks refcounting loop.
1065}
1066
1067// An unregistered service should remain unregistered, but its contents should
1068// be saved to the specified profile nonetheless.
1069TEST_F(ManagerTest, ConfigureUnregisteredServiceWithProfile) {
1070 scoped_refptr<MockProfile> profile0(
1071 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1072 scoped_refptr<MockProfile> profile1(
1073 new NiceMock<MockProfile>(control_interface(), manager(), ""));
1074
1075 const string kProfileName0 = "profile0";
1076 const string kProfileName1 = "profile1";
1077
1078 EXPECT_CALL(*profile0, GetRpcIdentifier())
1079 .WillRepeatedly(Return(kProfileName0));
1080 EXPECT_CALL(*profile1, GetRpcIdentifier())
1081 .WillRepeatedly(Return(kProfileName1));
1082
1083 AdoptProfile(manager(), profile0);
1084 AdoptProfile(manager(), profile1); // profile1 is now the ActiveProfile.
1085
1086 const std::vector<uint8_t> ssid;
1087 scoped_refptr<MockWiFiService> service(
1088 new NiceMock<MockWiFiService>(control_interface(),
1089 dispatcher(),
1090 metrics(),
1091 manager(),
1092 mock_wifi_,
1093 ssid,
1094 "",
1095 "",
1096 false));
1097
1098 service->set_profile(profile1);
1099
1100 // A separate MockWiFi from mock_wifi_ is used in the Manager since using
1101 // the same device as that used above causes a refcounting loop.
1102 scoped_refptr<MockWiFi> wifi(new NiceMock<MockWiFi>(control_interface(),
1103 dispatcher(),
1104 metrics(),
1105 manager(),
1106 "wifi1",
1107 "addr5",
1108 5));
1109 manager()->RegisterDevice(wifi);
1110 EXPECT_CALL(*wifi, GetService(_, _))
1111 .WillOnce(Return(service));
1112 EXPECT_CALL(*profile0, UpdateService(ServiceRefPtr(service.get())))
1113 .WillOnce(Return(true));
1114 EXPECT_CALL(*profile0, AdoptService(_))
1115 .Times(0);
1116 EXPECT_CALL(*profile1, AdoptService(_))
1117 .Times(0);
1118
1119 KeyValueStore args;
1120 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1121 args.SetString(flimflam::kProfileProperty, kProfileName0);
1122 Error error;
1123 manager()->ConfigureService(args, &error);
1124 EXPECT_TRUE(error.IsSuccess());
1125}
1126
Paul Stewart22aa71b2011-09-16 12:15:11 -07001127TEST_F(ManagerTest, TechnologyOrder) {
1128 Error error;
1129 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
1130 string(flimflam::kTypeWifi), &error);
1131 ASSERT_TRUE(error.IsSuccess());
1132 EXPECT_EQ(manager()->GetTechnologyOrder(),
1133 string(flimflam::kTypeEthernet) + "," +
1134 string(flimflam::kTypeWifi));
1135
1136 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
1137 string(flimflam::kTypeWifi), &error);
1138 ASSERT_FALSE(error.IsSuccess());
1139 EXPECT_EQ(Error::kInvalidArguments, error.type());
1140 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
1141 string(flimflam::kTypeWifi),
1142 manager()->GetTechnologyOrder());
1143}
1144
1145TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +00001146 // TODO(quiche): Some of these tests would probably fit better in
1147 // service_unittest, since the actual comparison of Services is
1148 // implemented in Service. (crosbug.com/23370)
1149
Paul Stewart22aa71b2011-09-16 12:15:11 -07001150 scoped_refptr<MockService> mock_service0(
1151 new NiceMock<MockService>(control_interface(),
1152 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001153 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001154 manager()));
1155 scoped_refptr<MockService> mock_service1(
1156 new NiceMock<MockService>(control_interface(),
1157 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001158 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -07001159 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001160
1161 manager()->RegisterService(mock_service0);
1162 manager()->RegisterService(mock_service1);
1163
1164 // Services should already be sorted by UniqueName
1165 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1166
1167 // Asking explictly to sort services should not change anything
1168 manager()->SortServices();
1169 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1170
1171 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +01001172 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001173 manager()->UpdateService(mock_service1);
1174 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1175
1176 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -07001177 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001178 manager()->UpdateService(mock_service0);
1179 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1180
1181 // Technology
1182 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
1183 .WillRepeatedly(Return(true));
1184 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
1185 .WillRepeatedly(Return(true));
1186 // NB: Redefine default (false) return values so we don't use the default rule
1187 // which makes the logs noisier
1188 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
1189 .WillRepeatedly(Return(false));
1190 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
1191 .WillRepeatedly(Return(false));
1192
1193 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -08001194 // Default technology ordering should favor Ethernet over WiFi.
1195 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001196 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1197
1198 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
1199 string(flimflam::kTypeEthernet), &error);
1200 EXPECT_TRUE(error.IsSuccess());
1201 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1202
Gaurav Shah435de2c2011-11-17 19:01:07 -08001203 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001204 mock_service0->set_priority(1);
1205 manager()->UpdateService(mock_service0);
1206 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1207
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001208 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +00001209 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -07001210 manager()->UpdateService(mock_service1);
1211 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1212
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001213 // Auto-connect.
1214 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001215 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001216 mock_service1->set_auto_connect(false);
1217 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001218 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1219
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001220 // Connectable.
1221 mock_service1->set_connectable(true);
1222 manager()->UpdateService(mock_service1);
1223 mock_service0->set_connectable(false);
1224 manager()->UpdateService(mock_service0);
1225 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1226
1227 // IsFailed.
1228 EXPECT_CALL(*mock_service0.get(), state())
1229 .WillRepeatedly(Return(Service::kStateIdle));
1230 EXPECT_CALL(*mock_service0.get(), IsFailed())
1231 .WillRepeatedly(Return(false));
1232 manager()->UpdateService(mock_service0);
1233 EXPECT_CALL(*mock_service0.get(), state())
1234 .WillRepeatedly(Return(Service::kStateFailure));
1235 EXPECT_CALL(*mock_service1.get(), IsFailed())
1236 .WillRepeatedly(Return(true));
1237 manager()->UpdateService(mock_service1);
1238 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1239
1240 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001241 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001242 .WillRepeatedly(Return(Service::kStateAssociating));
1243 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001244 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001245 manager()->UpdateService(mock_service1);
1246 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1247
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001248 // Connected.
1249 EXPECT_CALL(*mock_service0.get(), state())
1250 .WillRepeatedly(Return(Service::kStateConnected));
1251 EXPECT_CALL(*mock_service0.get(), IsConnected())
1252 .WillRepeatedly(Return(true));
1253 manager()->UpdateService(mock_service0);
1254 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1255
Paul Stewart22aa71b2011-09-16 12:15:11 -07001256 manager()->DeregisterService(mock_service0);
1257 manager()->DeregisterService(mock_service1);
1258}
1259
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001260TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001261 MockMetrics mock_metrics;
1262 manager()->set_metrics(&mock_metrics);
1263
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001264 scoped_refptr<MockService> mock_service0(
1265 new NiceMock<MockService>(control_interface(),
1266 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001267 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001268 manager()));
1269 scoped_refptr<MockService> mock_service1(
1270 new NiceMock<MockService>(control_interface(),
1271 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001272 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001273 manager()));
1274
1275 scoped_refptr<MockConnection> mock_connection0(
1276 new NiceMock<MockConnection>(device_info_.get()));
1277 scoped_refptr<MockConnection> mock_connection1(
1278 new NiceMock<MockConnection>(device_info_.get()));
1279
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001280 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001281 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001282 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001283 manager()->RegisterService(mock_service1);
1284
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001285 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1286 manager()->SortServices();
1287
1288 mock_service1->set_priority(1);
1289 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1290 manager()->SortServices();
1291
1292 mock_service1->set_priority(0);
1293 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1294 manager()->SortServices();
1295
Paul Stewartce4ec192012-03-14 12:53:46 -07001296 mock_service0->set_mock_connection(mock_connection0);
1297 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001298
1299 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001300 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001301 manager()->SortServices();
1302
1303 mock_service1->set_priority(1);
1304 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1305 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001306 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001307 manager()->SortServices();
1308
1309 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001310 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001311 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001312 manager()->DeregisterService(mock_service1);
1313
Paul Stewartce4ec192012-03-14 12:53:46 -07001314 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001315 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001316 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001317
1318 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1319 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001320}
1321
Gaurav Shah435de2c2011-11-17 19:01:07 -08001322TEST_F(ManagerTest, AvailableTechnologies) {
1323 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1324 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001325 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001326 manager(),
1327 "null4",
1328 "addr4",
1329 0));
1330 manager()->RegisterDevice(mock_devices_[0]);
1331 manager()->RegisterDevice(mock_devices_[1]);
1332 manager()->RegisterDevice(mock_devices_[2]);
1333 manager()->RegisterDevice(mock_devices_[3]);
1334
1335 ON_CALL(*mock_devices_[0].get(), technology())
1336 .WillByDefault(Return(Technology::kEthernet));
1337 ON_CALL(*mock_devices_[1].get(), technology())
1338 .WillByDefault(Return(Technology::kWifi));
1339 ON_CALL(*mock_devices_[2].get(), technology())
1340 .WillByDefault(Return(Technology::kCellular));
1341 ON_CALL(*mock_devices_[3].get(), technology())
1342 .WillByDefault(Return(Technology::kWifi));
1343
1344 set<string> expected_technologies;
1345 expected_technologies.insert(Technology::NameFromIdentifier(
1346 Technology::kEthernet));
1347 expected_technologies.insert(Technology::NameFromIdentifier(
1348 Technology::kWifi));
1349 expected_technologies.insert(Technology::NameFromIdentifier(
1350 Technology::kCellular));
1351 Error error;
1352 vector<string> technologies = manager()->AvailableTechnologies(&error);
1353
1354 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1355 ContainerEq(expected_technologies));
1356}
1357
1358TEST_F(ManagerTest, ConnectedTechnologies) {
1359 scoped_refptr<MockService> connected_service1(
1360 new NiceMock<MockService>(control_interface(),
1361 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001362 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001363 manager()));
1364 scoped_refptr<MockService> connected_service2(
1365 new NiceMock<MockService>(control_interface(),
1366 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001367 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001368 manager()));
1369 scoped_refptr<MockService> disconnected_service1(
1370 new NiceMock<MockService>(control_interface(),
1371 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001372 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001373 manager()));
1374 scoped_refptr<MockService> disconnected_service2(
1375 new NiceMock<MockService>(control_interface(),
1376 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001377 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001378 manager()));
1379
1380 ON_CALL(*connected_service1.get(), IsConnected())
1381 .WillByDefault(Return(true));
1382 ON_CALL(*connected_service2.get(), IsConnected())
1383 .WillByDefault(Return(true));
1384
1385 manager()->RegisterService(connected_service1);
1386 manager()->RegisterService(connected_service2);
1387 manager()->RegisterService(disconnected_service1);
1388 manager()->RegisterService(disconnected_service2);
1389
1390 manager()->RegisterDevice(mock_devices_[0]);
1391 manager()->RegisterDevice(mock_devices_[1]);
1392 manager()->RegisterDevice(mock_devices_[2]);
1393 manager()->RegisterDevice(mock_devices_[3]);
1394
1395 ON_CALL(*mock_devices_[0].get(), technology())
1396 .WillByDefault(Return(Technology::kEthernet));
1397 ON_CALL(*mock_devices_[1].get(), technology())
1398 .WillByDefault(Return(Technology::kWifi));
1399 ON_CALL(*mock_devices_[2].get(), technology())
1400 .WillByDefault(Return(Technology::kCellular));
1401 ON_CALL(*mock_devices_[3].get(), technology())
1402 .WillByDefault(Return(Technology::kWifi));
1403
1404 mock_devices_[0]->SelectService(connected_service1);
1405 mock_devices_[1]->SelectService(disconnected_service1);
1406 mock_devices_[2]->SelectService(disconnected_service2);
1407 mock_devices_[3]->SelectService(connected_service2);
1408
1409 set<string> expected_technologies;
1410 expected_technologies.insert(Technology::NameFromIdentifier(
1411 Technology::kEthernet));
1412 expected_technologies.insert(Technology::NameFromIdentifier(
1413 Technology::kWifi));
1414 Error error;
1415
1416 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1417 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1418 ContainerEq(expected_technologies));
1419}
1420
1421TEST_F(ManagerTest, DefaultTechnology) {
1422 scoped_refptr<MockService> connected_service(
1423 new NiceMock<MockService>(control_interface(),
1424 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001425 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001426 manager()));
1427 scoped_refptr<MockService> disconnected_service(
1428 new NiceMock<MockService>(control_interface(),
1429 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001430 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001431 manager()));
1432
1433 // Connected. WiFi.
1434 ON_CALL(*connected_service.get(), IsConnected())
1435 .WillByDefault(Return(true));
1436 ON_CALL(*connected_service.get(), state())
1437 .WillByDefault(Return(Service::kStateConnected));
1438 ON_CALL(*connected_service.get(), technology())
1439 .WillByDefault(Return(Technology::kWifi));
1440
1441 // Disconnected. Ethernet.
1442 ON_CALL(*disconnected_service.get(), technology())
1443 .WillByDefault(Return(Technology::kEthernet));
1444
1445 manager()->RegisterService(disconnected_service);
1446 Error error;
1447 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1448
1449
1450 manager()->RegisterService(connected_service);
1451 // Connected service should be brought to the front now.
1452 string expected_technology =
1453 Technology::NameFromIdentifier(Technology::kWifi);
1454 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1455}
1456
Thieu Le1271d682011-11-02 22:48:19 +00001457TEST_F(ManagerTest, DisconnectServicesOnStop) {
1458 scoped_refptr<MockService> mock_service(
1459 new NiceMock<MockService>(control_interface(),
1460 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001461 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001462 manager()));
1463 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001464 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001465 manager()->Stop();
1466}
1467
mukesh agrawal00917ce2011-11-22 23:56:55 +00001468TEST_F(ManagerTest, UpdateServiceConnected) {
1469 scoped_refptr<MockService> mock_service(
1470 new NiceMock<MockService>(control_interface(),
1471 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001472 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001473 manager()));
1474 manager()->RegisterService(mock_service);
1475 EXPECT_FALSE(mock_service->favorite());
1476 EXPECT_FALSE(mock_service->auto_connect());
1477
Gaurav Shah435de2c2011-11-17 19:01:07 -08001478 EXPECT_CALL(*mock_service.get(), IsConnected())
1479 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001480 manager()->UpdateService(mock_service);
1481 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1482 // to mock out MakeFavorite. And mocking that out would break the
1483 // SortServices test. (crosbug.com/23370)
1484 EXPECT_TRUE(mock_service->favorite());
1485 EXPECT_TRUE(mock_service->auto_connect());
1486}
1487
Thieu Led4e9e552012-02-16 16:26:07 -08001488TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1489 // This tests the case where the user connects to a service that is
1490 // currently associated with a profile. We want to make sure that the
1491 // favorite flag is set and that the flag is saved to the current
1492 // profile.
1493 scoped_refptr<MockService> mock_service(
1494 new NiceMock<MockService>(control_interface(),
1495 dispatcher(),
1496 metrics(),
1497 manager()));
1498 manager()->RegisterService(mock_service);
1499 EXPECT_FALSE(mock_service->favorite());
1500 EXPECT_FALSE(mock_service->auto_connect());
1501
1502 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1503 mock_service->set_profile(profile);
1504
1505 EXPECT_CALL(*mock_service.get(), IsConnected())
1506 .WillRepeatedly(Return(true));
1507 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1508 manager()->UpdateService(mock_service);
1509 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1510 // to mock out MakeFavorite. And mocking that out would break the
1511 // SortServices test. (crosbug.com/23370)
1512 EXPECT_TRUE(mock_service->favorite());
1513 EXPECT_TRUE(mock_service->auto_connect());
1514}
1515
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001516TEST_F(ManagerTest, SaveSuccessfulService) {
1517 scoped_refptr<MockProfile> profile(
1518 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1519 AdoptProfile(manager(), profile);
1520 scoped_refptr<MockService> service(
1521 new NiceMock<MockService>(control_interface(),
1522 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001523 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001524 manager()));
1525
1526 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1527 ServiceRefPtr expect_service(service.get());
1528
1529 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1530 .WillOnce(Return(false));
1531 manager()->RegisterService(service);
1532
1533 EXPECT_CALL(*service.get(), state())
1534 .WillRepeatedly(Return(Service::kStateConnected));
1535 EXPECT_CALL(*service.get(), IsConnected())
1536 .WillRepeatedly(Return(true));
1537 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1538 .WillOnce(Return(true));
1539 manager()->UpdateService(service);
1540}
1541
Paul Stewart1b253142012-01-26 14:05:52 -08001542TEST_F(ManagerTest, EnumerateProfiles) {
1543 vector<string> profile_paths;
1544 for (size_t i = 0; i < 10; i++) {
1545 scoped_refptr<MockProfile> profile(
1546 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001547 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001548 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1549 .WillOnce(Return(profile_paths.back()));
1550 AdoptProfile(manager(), profile);
1551 }
1552
1553 Error error;
1554 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1555 EXPECT_TRUE(error.IsSuccess());
1556 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1557 for (size_t i = 0; i < profile_paths.size(); i++) {
1558 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1559 }
1560}
1561
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001562TEST_F(ManagerTest, AutoConnectOnRegister) {
1563 MockServiceRefPtr service = MakeAutoConnectableService();
1564 EXPECT_CALL(*service.get(), AutoConnect());
1565 manager()->RegisterService(service);
1566 dispatcher()->DispatchPendingEvents();
1567}
1568
1569TEST_F(ManagerTest, AutoConnectOnUpdate) {
1570 MockServiceRefPtr service1 = MakeAutoConnectableService();
1571 service1->set_priority(1);
1572 MockServiceRefPtr service2 = MakeAutoConnectableService();
1573 service2->set_priority(2);
1574 manager()->RegisterService(service1);
1575 manager()->RegisterService(service2);
1576 dispatcher()->DispatchPendingEvents();
1577
1578 EXPECT_CALL(*service1.get(), AutoConnect());
1579 EXPECT_CALL(*service2.get(), state())
1580 .WillRepeatedly(Return(Service::kStateFailure));
1581 EXPECT_CALL(*service2.get(), IsFailed())
1582 .WillRepeatedly(Return(true));
1583 EXPECT_CALL(*service2.get(), IsConnected())
1584 .WillRepeatedly(Return(false));
1585 manager()->UpdateService(service2);
1586 dispatcher()->DispatchPendingEvents();
1587}
1588
1589TEST_F(ManagerTest, AutoConnectOnDeregister) {
1590 MockServiceRefPtr service1 = MakeAutoConnectableService();
1591 service1->set_priority(1);
1592 MockServiceRefPtr service2 = MakeAutoConnectableService();
1593 service2->set_priority(2);
1594 manager()->RegisterService(service1);
1595 manager()->RegisterService(service2);
1596 dispatcher()->DispatchPendingEvents();
1597
1598 EXPECT_CALL(*service1.get(), AutoConnect());
1599 manager()->DeregisterService(service2);
1600 dispatcher()->DispatchPendingEvents();
1601}
1602
Paul Stewartc681fa02012-03-02 19:40:04 -08001603TEST_F(ManagerTest, RecheckPortal) {
1604 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1605 .WillOnce(Return(false));
1606 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1607 .WillOnce(Return(true));
1608 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1609 .Times(0);
1610
1611 manager()->RegisterDevice(mock_devices_[0]);
1612 manager()->RegisterDevice(mock_devices_[1]);
1613 manager()->RegisterDevice(mock_devices_[2]);
1614
1615 manager()->RecheckPortal(NULL);
1616}
1617
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001618TEST_F(ManagerTest, GetDefaultService) {
1619 EXPECT_FALSE(manager()->GetDefaultService().get());
1620
1621 scoped_refptr<MockService> mock_service(
1622 new NiceMock<MockService>(control_interface(),
1623 dispatcher(),
1624 metrics(),
1625 manager()));
1626
1627 manager()->RegisterService(mock_service);
1628 EXPECT_FALSE(manager()->GetDefaultService().get());
1629
1630 scoped_refptr<MockConnection> mock_connection(
1631 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001632 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001633 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1634
Paul Stewartce4ec192012-03-14 12:53:46 -07001635 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001636 manager()->DeregisterService(mock_service);
1637}
1638
Paul Stewart13ed2252012-03-21 12:52:46 -07001639TEST_F(ManagerTest, GetServiceWithGUID) {
1640 scoped_refptr<MockService> mock_service0(
1641 new NiceMock<MockService>(control_interface(),
1642 dispatcher(),
1643 metrics(),
1644 manager()));
1645
1646 scoped_refptr<MockService> mock_service1(
1647 new NiceMock<MockService>(control_interface(),
1648 dispatcher(),
1649 metrics(),
1650 manager()));
1651
Paul Stewartcb59fed2012-03-21 21:14:46 -07001652 EXPECT_CALL(*mock_service0.get(), Configure(_, _))
1653 .Times(0);
1654 EXPECT_CALL(*mock_service1.get(), Configure(_, _))
1655 .Times(0);
1656
Paul Stewart13ed2252012-03-21 12:52:46 -07001657 manager()->RegisterService(mock_service0);
1658 manager()->RegisterService(mock_service1);
1659
1660 const string kGUID0 = "GUID0";
1661 const string kGUID1 = "GUID1";
1662
1663 {
1664 Error error;
1665 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1666 EXPECT_FALSE(error.IsSuccess());
1667 EXPECT_FALSE(service);
1668 }
1669
1670 KeyValueStore args;
1671 args.SetString(flimflam::kGuidProperty, kGUID1);
1672
1673 {
1674 Error error;
1675 ServiceRefPtr service = manager()->GetService(args, &error);
1676 EXPECT_EQ(Error::kInvalidArguments, error.type());
1677 EXPECT_FALSE(service);
1678 }
1679
1680 mock_service0->set_guid(kGUID0);
1681 mock_service1->set_guid(kGUID1);
1682
1683 {
1684 Error error;
1685 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1686 EXPECT_TRUE(error.IsSuccess());
1687 EXPECT_EQ(mock_service0.get(), service.get());
1688 }
1689
1690 {
1691 Error error;
Paul Stewartcb59fed2012-03-21 21:14:46 -07001692 EXPECT_CALL(*mock_service1.get(), Configure(_, &error))
1693 .Times(1);
Paul Stewart13ed2252012-03-21 12:52:46 -07001694 ServiceRefPtr service = manager()->GetService(args, &error);
1695 EXPECT_TRUE(error.IsSuccess());
1696 EXPECT_EQ(mock_service1.get(), service.get());
1697 }
1698
1699 manager()->DeregisterService(mock_service0);
1700 manager()->DeregisterService(mock_service1);
1701}
1702
Chris Masone9be4a9d2011-05-16 15:44:09 -07001703} // namespace shill