blob: 8d35b2e91a05a9ac0737ca80f5a09baefb24f88f [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"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070037#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070038#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039
40using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070041using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042using std::string;
43using std::vector;
44
Chris Masone9be4a9d2011-05-16 15:44:09 -070045namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070046using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070047using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080048using ::testing::ContainerEq;
Paul Stewarte2bad7c2012-03-14 08:55:33 -070049using ::testing::InSequence;
Paul Stewart22aa71b2011-09-16 12:15:11 -070050using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070051using ::testing::NiceMock;
52using ::testing::Return;
Paul Stewartce4ec192012-03-14 12:53:46 -070053using ::testing::ReturnRef;
Gaurav Shah435de2c2011-11-17 19:01:07 -080054using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080055using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070056using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070057
Chris Masone3bd3c8c2011-06-13 08:20:26 -070058class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070059 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070060 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070061 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070062 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080063 metrics(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070064 manager(),
65 "wifi0",
66 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080067 4)),
68 device_info_(new NiceMock<MockDeviceInfo>(
69 control_interface(),
70 reinterpret_cast<EventDispatcher*>(NULL),
Thieu Le3426c8f2012-01-11 17:35:11 -080071 reinterpret_cast<Metrics*>(NULL),
Paul Stewartc1dec4d2011-12-08 15:25:28 -080072 reinterpret_cast<Manager*>(NULL))),
73 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070074 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
75 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080076 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070077 manager(),
78 "null0",
79 "addr0",
80 0));
81 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
82 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080083 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070084 manager(),
85 "null1",
86 "addr1",
87 1));
88 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
89 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080090 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -070091 manager(),
92 "null2",
93 "addr2",
94 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080095 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
96 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080097 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -080098 manager(),
99 "null3",
100 "addr3",
101 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700102 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800103
104 // Replace the manager's adaptor with a quieter one, and one
105 // we can do EXPECT*() against. Passes ownership.
106 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700107 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700108 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700109
Paul Stewartfdd16072011-09-16 12:41:35 -0700110 bool IsDeviceRegistered(const DeviceRefPtr &device,
111 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700112 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700113 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700114 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700115 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700116 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700117
Paul Stewarta849a3d2011-11-03 05:54:09 -0700118 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
119 manager->profiles_.push_back(profile);
120 }
121
Paul Stewart75225512012-01-26 22:51:33 -0800122 ProfileRefPtr GetEphemeralProfile(Manager *manager) {
123 return manager->ephemeral_profile_;
124 }
125
Chris Masone6515aab2011-10-12 16:19:09 -0700126 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
127 Profile::Identifier id("rather", "irrelevant");
128 scoped_ptr<Profile> profile(new Profile(control_interface(),
129 manager,
130 id,
131 "",
132 false));
133 FilePath final_path(storage_path());
134 final_path = final_path.Append("test.profile");
135 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
136 storage->set_path(final_path);
137 if (!storage->Open())
138 return NULL;
139 profile->set_storage(storage.release()); // Passes ownership.
140 return profile.release();
141 }
142
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700143 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
144 const string &profile_identifier,
145 const string &service_name) {
146 GLib glib;
147 KeyFileStore store(&glib);
148 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
149 return store.Open() &&
150 store.SetString(service_name, "rather", "irrelevant") &&
151 store.Close();
152 }
153
154 Error::Type TestCreateProfile(Manager *manager, const string &name) {
155 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800156 string path;
157 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700158 return error.type();
159 }
160
161 Error::Type TestPopAnyProfile(Manager *manager) {
162 Error error;
163 manager->PopAnyProfile(&error);
164 return error.type();
165 }
166
167 Error::Type TestPopProfile(Manager *manager, const string &name) {
168 Error error;
169 manager->PopProfile(name, &error);
170 return error.type();
171 }
172
173 Error::Type TestPushProfile(Manager *manager, const string &name) {
174 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800175 string path;
176 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700177 return error.type();
178 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000179
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700180 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000181 typedef scoped_refptr<MockService> MockServiceRefPtr;
182
183 MockServiceRefPtr MakeAutoConnectableService() {
184 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
185 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800186 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000187 manager());
188 service->MakeFavorite();
189 service->set_connectable(true);
190 return service;
191 }
192
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700193 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700194 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800195 scoped_ptr<MockDeviceInfo> device_info_;
196
197 // This pointer is owned by the manager, and only tracked here for EXPECT*()
198 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700199};
200
Paul Stewart22aa71b2011-09-16 12:15:11 -0700201bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
202 return (svc0.get() == manager()->services_[0].get() &&
203 svc1.get() == manager()->services_[1].get());
204}
205
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700206TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700207 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
208 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700209}
210
Chris Masone9be4a9d2011-05-16 15:44:09 -0700211TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700212 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700213 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700214 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700215 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700216 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700217 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700218
Paul Stewart22aa71b2011-09-16 12:15:11 -0700219 manager()->RegisterDevice(mock_devices_[0]);
220 manager()->RegisterDevice(mock_devices_[1]);
221 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700222
Paul Stewart22aa71b2011-09-16 12:15:11 -0700223 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
224 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
225 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700226}
227
Paul Stewarta41e38d2011-11-11 07:47:29 -0800228TEST_F(ManagerTest, DeviceRegistrationAndStart) {
229 manager()->running_ = true;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500230 mock_devices_[0]->enabled_persistent_ = true;
231 mock_devices_[1]->enabled_persistent_ = false;
232 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(true))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800233 .Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500234 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(_))
Paul Stewarta41e38d2011-11-11 07:47:29 -0800235 .Times(0);
236 manager()->RegisterDevice(mock_devices_[0]);
237 manager()->RegisterDevice(mock_devices_[1]);
238}
239
240TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
241 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
242 DeviceRefPtr device_ref(mock_devices_[0].get());
243 AdoptProfile(manager(), profile); // Passes ownership.
244 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
245 EXPECT_CALL(*profile, Save());
246 manager()->RegisterDevice(mock_devices_[0]);
247}
248
Chris Masone9be4a9d2011-05-16 15:44:09 -0700249TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700250 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700251 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700252 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700253 .WillByDefault(Return(true));
254
Gaurav Shah435de2c2011-11-17 19:01:07 -0800255 manager()->RegisterDevice(mock_devices_[0]);
256 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700257
Paul Stewart22aa71b2011-09-16 12:15:11 -0700258 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
259 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700260
Eric Shienbrood9a245532012-03-07 14:20:39 -0500261 EXPECT_CALL(*mock_devices_[0].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800262 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700263 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700264
Eric Shienbrood9a245532012-03-07 14:20:39 -0500265 EXPECT_CALL(*mock_devices_[1].get(), SetEnabled(false));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800266 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700267 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700268}
269
270TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700271 // It's much easier and safer to use a real GLib for this test.
272 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700273 Manager manager(control_interface(),
274 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800275 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700276 &glib,
277 run_path(),
278 storage_path(),
279 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700280 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
281 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700282 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700283
Chris Masone9be4a9d2011-05-16 15:44:09 -0700284 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700285 new NiceMock<MockService>(control_interface(),
286 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800287 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700288 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700289 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700290 new NiceMock<MockService>(control_interface(),
291 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800292 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700293 &manager));
Paul Stewartce4ec192012-03-14 12:53:46 -0700294
mukesh agrawal51a7e932011-07-27 16:18:26 -0700295 string service1_name(mock_service->UniqueName());
296 string service2_name(mock_service2->UniqueName());
297
298 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
299 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700300 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700301 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700302 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700303 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700304 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700305
Chris Masone9d779932011-08-25 16:33:41 -0700306 manager.RegisterService(mock_service);
307 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700308
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800309 Error error;
310 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700311 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700312 EXPECT_EQ(2, ids.size());
313 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
314 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700315
Chris Masone9d779932011-08-25 16:33:41 -0700316 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
317 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
318
319 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700320}
321
Chris Masone6515aab2011-10-12 16:19:09 -0700322TEST_F(ManagerTest, RegisterKnownService) {
323 // It's much easier and safer to use a real GLib for this test.
324 GLib glib;
325 Manager manager(control_interface(),
326 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800327 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700328 &glib,
329 run_path(),
330 storage_path(),
331 string());
332 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
333 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700334 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700335 {
336 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
337 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800338 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700339 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700340 ASSERT_TRUE(profile->AdoptService(service1));
341 ASSERT_TRUE(profile->ContainsService(service1));
342 } // Force destruction of service1.
343
344 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
345 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800346 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700347 &manager));
348 manager.RegisterService(service2);
349 EXPECT_EQ(service2->profile().get(), profile.get());
350 manager.Stop();
351}
352
353TEST_F(ManagerTest, RegisterUnknownService) {
354 // It's much easier and safer to use a real GLib for this test.
355 GLib glib;
356 Manager manager(control_interface(),
357 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800358 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700359 &glib,
360 run_path(),
361 storage_path(),
362 string());
363 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
364 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700365 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700366 {
367 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
368 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800369 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700370 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700371 ASSERT_TRUE(profile->AdoptService(service1));
372 ASSERT_TRUE(profile->ContainsService(service1));
373 } // Force destruction of service1.
374 scoped_refptr<MockService> mock_service2(
375 new NiceMock<MockService>(control_interface(),
376 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800377 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700378 &manager));
379 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
380 .WillRepeatedly(Return(mock_service2->UniqueName()));
381 manager.RegisterService(mock_service2);
382 EXPECT_NE(mock_service2->profile().get(), profile.get());
383 manager.Stop();
384}
385
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000386TEST_F(ManagerTest, DeregisterUnregisteredService) {
387 // WiFi assumes that it can deregister a service that is not
388 // registered. (E.g. a hidden service can be deregistered when it
389 // loses its last endpoint, and again when WiFi is Stop()-ed.)
390 //
391 // So test that doing so doesn't cause a crash.
392 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
393 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800394 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000395 manager());
396 manager()->DeregisterService(service);
397}
398
Chris Masonea8a2c252011-06-27 22:16:30 -0700399TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700400 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700401 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700402 map<string, ::DBus::Variant> props;
403 Error error(Error::kInvalidProperty, "");
404 {
405 ::DBus::Error dbus_error;
406 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700407 manager()->mutable_store()->SetStringProperty(
408 flimflam::kCheckPortalListProperty,
409 expected,
410 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700411 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700412 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
413 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
414 expected);
415 }
416 {
417 ::DBus::Error dbus_error;
418 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700419 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
420 expected,
421 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700422 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700423 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
424 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
425 expected);
426 }
427}
428
Chris Masone3c3f6a12011-07-01 10:01:41 -0700429TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700430 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700431 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800432 manager()->RegisterDevice(mock_devices_[0]);
433 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700434 {
435 map<string, ::DBus::Variant> props;
436 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700437 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700438 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
439 Strings devices =
440 props[flimflam::kDevicesProperty].operator vector<string>();
441 EXPECT_EQ(2, devices.size());
442 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700443}
444
mukesh agrawal2366eed2012-03-20 18:21:50 -0700445TEST_F(ManagerTest, GetServicesProperty) {
446 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
447 AdoptProfile(manager(), profile);
448 map<string, ::DBus::Variant> props;
449 ::DBus::Error dbus_error;
450 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
451 map<string, ::DBus::Variant>::const_iterator prop =
452 props.find(flimflam::kServicesProperty);
453 ASSERT_FALSE(prop == props.end());
454 const ::DBus::Variant &variant = prop->second;
455 ASSERT_TRUE(DBusAdaptor::IsPaths(variant.signature()));
456}
457
Chris Masone6791a432011-07-12 13:23:19 -0700458TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700459 Manager manager(control_interface(),
460 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800461 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700462 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700463 run_path(),
464 storage_path(),
465 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700466 scoped_refptr<MockService> s2(new MockService(control_interface(),
467 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800468 metrics(),
Chris Masone6515aab2011-10-12 16:19:09 -0700469 &manager));
470 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700471 {
Chris Masone6515aab2011-10-12 16:19:09 -0700472 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700473 ProfileRefPtr profile(
474 new Profile(control_interface(), &manager, id, "", false));
475 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700476 // Say we don't have |s2| the first time asked, then that we do.
477 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
478 .WillOnce(Return(false))
479 .WillRepeatedly(Return(true));
480 EXPECT_CALL(*storage, Flush())
481 .Times(AnyNumber())
482 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700483 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700484 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700485 }
Chris Masone6515aab2011-10-12 16:19:09 -0700486 // Create a profile that already has |s2| in it.
487 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
488 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700489
Chris Masone6515aab2011-10-12 16:19:09 -0700490 // Now, move the Service |s2| to another profile.
491 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
492 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700493
494 // Force destruction of the original Profile, to ensure that the Service
495 // is kept alive and populated with data.
496 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700497 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700498 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700499}
500
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800501TEST_F(ManagerTest, SetProfileForService) {
502 scoped_refptr<MockProfile> profile0(
503 new MockProfile(control_interface(), manager(), ""));
504 string profile_name0("profile0");
505 EXPECT_CALL(*profile0, GetRpcIdentifier())
506 .WillRepeatedly(Return(profile_name0));
507 AdoptProfile(manager(), profile0);
508 scoped_refptr<MockService> service(new MockService(control_interface(),
509 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800510 metrics(),
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800511 manager()));
512 service->set_profile(profile0);
513
514 {
515 Error error;
516 manager()->SetProfileForService(service, "foo", &error);
517 EXPECT_EQ(Error::kInvalidArguments, error.type());
518 EXPECT_EQ("Unknown Profile requested for Service", error.message());
519 }
520
521 {
522 Error error;
523 manager()->SetProfileForService(service, profile_name0, &error);
524 EXPECT_EQ(Error::kInvalidArguments, error.type());
525 EXPECT_EQ("Service is already connected to this profile", error.message());
526 }
527
528 scoped_refptr<MockProfile> profile1(
529 new MockProfile(control_interface(), manager(), ""));
530 string profile_name1("profile1");
531 EXPECT_CALL(*profile1, GetRpcIdentifier())
532 .WillRepeatedly(Return(profile_name1));
533 AdoptProfile(manager(), profile1);
534
535 {
536 Error error;
537 EXPECT_CALL(*profile1, AdoptService(_))
538 .WillOnce(Return(true));
539 EXPECT_CALL(*profile0, AbandonService(_))
540 .WillOnce(Return(true));
541 manager()->SetProfileForService(service, profile_name1, &error);
542 EXPECT_TRUE(error.IsSuccess());
543 }
544}
545
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700546TEST_F(ManagerTest, CreateProfile) {
547 // It's much easier to use real Glib here since we want the storage
548 // side-effects.
549 GLib glib;
550 ScopedTempDir temp_dir;
551 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
552
553 Manager manager(control_interface(),
554 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800555 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700556 &glib,
557 run_path(),
558 storage_path(),
559 temp_dir.path().value());
560
561 // Invalid name should be rejected.
562 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
563
564 // Valid name is still rejected because we can't create a profile
565 // that doesn't have a user component. Such profile names are
566 // reserved for the single DefaultProfile the manager creates
567 // at startup.
568 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, "valid"));
569
570 // We should succeed in creating a valid user profile.
571 const char kProfile[] = "~user/profile";
572 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
573
574 // We should fail in creating it a second time (already exists).
575 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
576}
577
578TEST_F(ManagerTest, PushPopProfile) {
579 // It's much easier to use real Glib in creating a Manager for this
580 // test here since we want the storage side-effects.
581 GLib glib;
582 ScopedTempDir temp_dir;
583 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
584 Manager manager(control_interface(),
585 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800586 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700587 &glib,
588 run_path(),
589 storage_path(),
590 temp_dir.path().value());
591
592 // Pushing an invalid profile should fail.
593 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
594
595 // Pushing a default profile name should fail.
596 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, "default"));
597
598 const char kProfile0[] = "~user/profile0";
599 const char kProfile1[] = "~user/profile1";
600
601 // Create a couple of profiles.
602 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
603 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
604
605 // Push these profiles on the stack.
606 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
607 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
608
609 // Pushing a profile a second time should fail.
610 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
611 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
612
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800613 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700614 // Active profile should be the last one we pushed.
Paul Stewart1b253142012-01-26 14:05:52 -0800615 EXPECT_EQ(kProfile1, "~" + manager.ActiveProfile()->GetFriendlyName());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700616
617 // Make sure a profile name that doesn't exist fails.
618 const char kProfile2Id[] = "profile2";
619 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
620 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
621
622 // Create a new service, with a specific storage name.
623 scoped_refptr<MockService> service(
624 new NiceMock<MockService>(control_interface(),
625 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800626 metrics(),
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700627 &manager));
628 const char kServiceName[] = "service_storage_name";
629 EXPECT_CALL(*service.get(), GetStorageIdentifier())
630 .WillRepeatedly(Return(kServiceName));
631 EXPECT_CALL(*service.get(), Load(_))
632 .WillRepeatedly(Return(true));
633
634 // Add this service to the manager -- it should end up in the ephemeral
635 // profile.
636 manager.RegisterService(service);
Paul Stewart75225512012-01-26 22:51:33 -0800637 ASSERT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700638
639 // Create storage for a profile that contains the service storage name.
640 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
641 kServiceName));
642
643 // When we push the profile, the service should move away from the
644 // ephemeral profile to this new profile since it has an entry for
645 // this service.
646 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
Paul Stewart75225512012-01-26 22:51:33 -0800647 EXPECT_NE(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700648 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
649
650 // Insert another profile that should supersede ownership of the service.
651 const char kProfile3Id[] = "profile3";
652 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
653 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
654 kServiceName));
655 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
656 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
657
658 // Popping an invalid profile name should fail.
659 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
660
661 // Popping an profile that is not at the top of the stack should fail.
662 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
663
664 // Popping the top profile should succeed.
665 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
666
667 // Moreover the service should have switched profiles to profile 2.
668 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
669
670 // Popping the top profile should succeed.
671 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
672
673 // The service should now revert to the ephemeral profile.
Paul Stewart75225512012-01-26 22:51:33 -0800674 EXPECT_EQ(GetEphemeralProfile(&manager), service->profile());
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700675
676 // Pop the remaining two services off the stack.
677 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
678 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
679
680 // Next pop should fail with "stack is empty".
681 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
682}
683
Paul Stewart75225512012-01-26 22:51:33 -0800684// Use this matcher instead of passing RefPtrs directly into the arguments
685// of EXPECT_CALL() because otherwise we may create un-cleaned-up references at
686// system teardown.
687MATCHER_P(IsRefPtrTo, ref_address, "") {
688 return arg.get() == ref_address;
689}
690
691TEST_F(ManagerTest, HandleProfileEntryDeletion) {
692 MockServiceRefPtr s_not_in_profile(
693 new NiceMock<MockService>(control_interface(),
694 dispatcher(),
695 metrics(),
696 manager()));
697 MockServiceRefPtr s_not_in_group(
698 new NiceMock<MockService>(control_interface(),
699 dispatcher(),
700 metrics(),
701 manager()));
702 MockServiceRefPtr s_configure_fail(
703 new NiceMock<MockService>(control_interface(),
704 dispatcher(),
705 metrics(),
706 manager()));
707 MockServiceRefPtr s_configure_succeed(
708 new NiceMock<MockService>(control_interface(),
709 dispatcher(),
710 metrics(),
711 manager()));
712
713 string entry_name("entry_name");
714 EXPECT_CALL(*s_not_in_profile.get(), GetStorageIdentifier()).Times(0);
715 EXPECT_CALL(*s_not_in_group.get(), GetStorageIdentifier())
716 .WillRepeatedly(Return("not_entry_name"));
717 EXPECT_CALL(*s_configure_fail.get(), GetStorageIdentifier())
718 .WillRepeatedly(Return(entry_name));
719 EXPECT_CALL(*s_configure_succeed.get(), GetStorageIdentifier())
720 .WillRepeatedly(Return(entry_name));
721
722 manager()->RegisterService(s_not_in_profile);
723 manager()->RegisterService(s_not_in_group);
724 manager()->RegisterService(s_configure_fail);
725 manager()->RegisterService(s_configure_succeed);
726
727 scoped_refptr<MockProfile> profile0(
728 new StrictMock<MockProfile>(control_interface(), manager(), ""));
729 scoped_refptr<MockProfile> profile1(
730 new StrictMock<MockProfile>(control_interface(), manager(), ""));
731
732 s_not_in_group->set_profile(profile1);
733 s_configure_fail->set_profile(profile1);
734 s_configure_succeed->set_profile(profile1);
735
736 AdoptProfile(manager(), profile0);
737 AdoptProfile(manager(), profile1);
738
739 // No services are a member of this profile.
740 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile0, entry_name));
741
742 // No services that are members of this profile have this entry name.
743 EXPECT_FALSE(manager()->HandleProfileEntryDeletion(profile1, ""));
744
745 // Only services that are members of the profile and group will be abandoned.
746 EXPECT_CALL(*profile1.get(),
747 AbandonService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
748 EXPECT_CALL(*profile1.get(),
749 AbandonService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
750 EXPECT_CALL(*profile1.get(),
751 AbandonService(IsRefPtrTo(s_configure_fail.get())))
752 .WillOnce(Return(true));
753 EXPECT_CALL(*profile1.get(),
754 AbandonService(IsRefPtrTo(s_configure_succeed.get())))
755 .WillOnce(Return(true));
756
757 // Never allow services to re-join profile1.
758 EXPECT_CALL(*profile1.get(), ConfigureService(_))
759 .WillRepeatedly(Return(false));
760
761 // Only allow one of the members of the profile and group to successfully
762 // join profile0.
763 EXPECT_CALL(*profile0.get(),
764 ConfigureService(IsRefPtrTo(s_not_in_profile.get()))).Times(0);
765 EXPECT_CALL(*profile0.get(),
766 ConfigureService(IsRefPtrTo(s_not_in_group.get()))).Times(0);
767 EXPECT_CALL(*profile0.get(),
768 ConfigureService(IsRefPtrTo(s_configure_fail.get())))
769 .WillOnce(Return(false));
770 EXPECT_CALL(*profile0.get(),
771 ConfigureService(IsRefPtrTo(s_configure_succeed.get())))
772 .WillOnce(Return(true));
773
774 // Expect the failed-to-configure service to have Unload() called on it.
775 EXPECT_CALL(*s_not_in_profile.get(), Unload()).Times(0);
776 EXPECT_CALL(*s_not_in_group.get(), Unload()).Times(0);
777 EXPECT_CALL(*s_configure_fail.get(), Unload()).Times(1);
778 EXPECT_CALL(*s_configure_succeed.get(), Unload()).Times(0);
779
780 EXPECT_TRUE(manager()->HandleProfileEntryDeletion(profile1, entry_name));
781
782 EXPECT_EQ(GetEphemeralProfile(manager()), s_not_in_profile->profile().get());
783 EXPECT_EQ(profile1, s_not_in_group->profile());
784 EXPECT_EQ(GetEphemeralProfile(manager()), s_configure_fail->profile());
785
786 // Since we are using a MockProfile, the profile does not actually change,
787 // since ConfigureService was not actually called on the service.
788 EXPECT_EQ(profile1, s_configure_succeed->profile());
789}
790
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800791TEST_F(ManagerTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700792 {
793 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800794 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
795 flimflam::kOfflineModeProperty,
796 PropertyStoreTest::kBoolV,
797 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700798 }
799 {
800 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800801 EXPECT_TRUE(DBusAdaptor::SetProperty(manager()->mutable_store(),
802 flimflam::kCountryProperty,
803 PropertyStoreTest::kStringV,
804 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700805 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700806 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700807 {
808 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800809 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
810 flimflam::kCountryProperty,
811 PropertyStoreTest::kBoolV,
812 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700813 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700814 }
815 {
816 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800817 EXPECT_FALSE(DBusAdaptor::SetProperty(manager()->mutable_store(),
818 flimflam::kOfflineModeProperty,
819 PropertyStoreTest::kStringV,
820 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700821 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700822 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700823 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700824 {
825 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800826 EXPECT_FALSE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700827 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700828 flimflam::kEnabledTechnologiesProperty,
829 PropertyStoreTest::kStringsV,
830 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700831 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700832 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700833}
834
mukesh agrawal32399322011-09-01 10:53:43 -0700835TEST_F(ManagerTest, RequestScan) {
836 {
837 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700838 manager()->RegisterDevice(mock_devices_[0].get());
839 manager()->RegisterDevice(mock_devices_[1].get());
840 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700841 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700842 EXPECT_CALL(*mock_devices_[0], Scan(_));
843 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700844 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700845 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -0700846 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700847 }
848
849 {
850 Error error;
Chris Masone9d779932011-08-25 16:33:41 -0700851 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700852 EXPECT_EQ(Error::kInvalidArguments, error.type());
853 }
854}
855
Darin Petkovb65c2452012-02-23 15:17:06 +0100856TEST_F(ManagerTest, GetServiceNoType) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700857 KeyValueStore args;
858 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100859 manager()->GetService(args, &e);
860 EXPECT_EQ(Error::kInvalidArguments, e.type());
861 EXPECT_EQ("must specify service type", e.message());
862}
863
864TEST_F(ManagerTest, GetServiceUnknownType) {
865 KeyValueStore args;
866 Error e;
867 args.SetString(flimflam::kTypeProperty, flimflam::kTypeEthernet);
868 manager()->GetService(args, &e);
869 EXPECT_EQ(Error::kNotSupported, e.type());
870 EXPECT_EQ("service type is unsupported", e.message());
871}
872
873TEST_F(ManagerTest, GetServiceNoWifiDevice) {
874 KeyValueStore args;
875 Error e;
876 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
877 manager()->GetService(args, &e);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700878 EXPECT_EQ(Error::kInvalidArguments, e.type());
879 EXPECT_EQ("no wifi devices available", e.message());
880}
881
Darin Petkovb65c2452012-02-23 15:17:06 +0100882TEST_F(ManagerTest, GetServiceWifi) {
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700883 KeyValueStore args;
884 Error e;
885 WiFiServiceRefPtr wifi_service;
Darin Petkovb65c2452012-02-23 15:17:06 +0100886 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700887 manager()->RegisterDevice(mock_wifi_);
888 EXPECT_CALL(*mock_wifi_, GetService(_, _))
889 .WillRepeatedly(Return(wifi_service));
Darin Petkovb65c2452012-02-23 15:17:06 +0100890 manager()->GetService(args, &e);
891 EXPECT_TRUE(e.IsSuccess());
892}
893
Darin Petkov33af05c2012-02-28 10:10:30 +0100894TEST_F(ManagerTest, GetServiceVPNUnknownType) {
895 KeyValueStore args;
896 Error e;
897 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
898 ServiceRefPtr service = manager()->GetService(args, &e);
899 EXPECT_EQ(Error::kNotSupported, e.type());
900 EXPECT_FALSE(service);
901}
902
Darin Petkovb65c2452012-02-23 15:17:06 +0100903TEST_F(ManagerTest, GetServiceVPN) {
904 KeyValueStore args;
905 Error e;
Darin Petkovb65c2452012-02-23 15:17:06 +0100906 args.SetString(flimflam::kTypeProperty, flimflam::kTypeVPN);
Darin Petkov33af05c2012-02-28 10:10:30 +0100907 args.SetString(flimflam::kProviderTypeProperty, flimflam::kProviderOpenVpn);
Darin Petkov02867712012-03-12 14:25:05 +0100908 args.SetString(flimflam::kProviderHostProperty, "10.8.0.1");
909 args.SetString(flimflam::kProviderNameProperty, "vpn-name");
Darin Petkov33af05c2012-02-28 10:10:30 +0100910 ServiceRefPtr service = manager()->GetService(args, &e);
911 EXPECT_TRUE(e.IsSuccess());
912 EXPECT_TRUE(service);
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700913}
914
Paul Stewart22aa71b2011-09-16 12:15:11 -0700915TEST_F(ManagerTest, TechnologyOrder) {
916 Error error;
917 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
918 string(flimflam::kTypeWifi), &error);
919 ASSERT_TRUE(error.IsSuccess());
920 EXPECT_EQ(manager()->GetTechnologyOrder(),
921 string(flimflam::kTypeEthernet) + "," +
922 string(flimflam::kTypeWifi));
923
924 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
925 string(flimflam::kTypeWifi), &error);
926 ASSERT_FALSE(error.IsSuccess());
927 EXPECT_EQ(Error::kInvalidArguments, error.type());
928 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
929 string(flimflam::kTypeWifi),
930 manager()->GetTechnologyOrder());
931}
932
933TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +0000934 // TODO(quiche): Some of these tests would probably fit better in
935 // service_unittest, since the actual comparison of Services is
936 // implemented in Service. (crosbug.com/23370)
937
Paul Stewart22aa71b2011-09-16 12:15:11 -0700938 scoped_refptr<MockService> mock_service0(
939 new NiceMock<MockService>(control_interface(),
940 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800941 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700942 manager()));
943 scoped_refptr<MockService> mock_service1(
944 new NiceMock<MockService>(control_interface(),
945 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800946 metrics(),
Paul Stewart22aa71b2011-09-16 12:15:11 -0700947 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700948
949 manager()->RegisterService(mock_service0);
950 manager()->RegisterService(mock_service1);
951
952 // Services should already be sorted by UniqueName
953 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
954
955 // Asking explictly to sort services should not change anything
956 manager()->SortServices();
957 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
958
959 // Two otherwise equal services should be reordered by strength
Darin Petkovd78ee7e2012-01-12 11:21:10 +0100960 mock_service1->SetStrength(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700961 manager()->UpdateService(mock_service1);
962 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
963
964 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -0700965 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700966 manager()->UpdateService(mock_service0);
967 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
968
969 // Technology
970 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
971 .WillRepeatedly(Return(true));
972 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
973 .WillRepeatedly(Return(true));
974 // NB: Redefine default (false) return values so we don't use the default rule
975 // which makes the logs noisier
976 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
977 .WillRepeatedly(Return(false));
978 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
979 .WillRepeatedly(Return(false));
980
981 Error error;
mukesh agrawal84de5d22012-02-17 19:29:15 -0800982 // Default technology ordering should favor Ethernet over WiFi.
983 manager()->SortServices();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700984 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
985
986 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
987 string(flimflam::kTypeEthernet), &error);
988 EXPECT_TRUE(error.IsSuccess());
989 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
990
Gaurav Shah435de2c2011-11-17 19:01:07 -0800991 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700992 mock_service0->set_priority(1);
993 manager()->UpdateService(mock_service0);
994 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
995
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000996 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +0000997 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700998 manager()->UpdateService(mock_service1);
999 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1000
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001001 // Auto-connect.
1002 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001003 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001004 mock_service1->set_auto_connect(false);
1005 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -07001006 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1007
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001008 // Connectable.
1009 mock_service1->set_connectable(true);
1010 manager()->UpdateService(mock_service1);
1011 mock_service0->set_connectable(false);
1012 manager()->UpdateService(mock_service0);
1013 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1014
1015 // IsFailed.
1016 EXPECT_CALL(*mock_service0.get(), state())
1017 .WillRepeatedly(Return(Service::kStateIdle));
1018 EXPECT_CALL(*mock_service0.get(), IsFailed())
1019 .WillRepeatedly(Return(false));
1020 manager()->UpdateService(mock_service0);
1021 EXPECT_CALL(*mock_service0.get(), state())
1022 .WillRepeatedly(Return(Service::kStateFailure));
1023 EXPECT_CALL(*mock_service1.get(), IsFailed())
1024 .WillRepeatedly(Return(true));
1025 manager()->UpdateService(mock_service1);
1026 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1027
1028 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -07001029 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001030 .WillRepeatedly(Return(Service::kStateAssociating));
1031 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -08001032 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -07001033 manager()->UpdateService(mock_service1);
1034 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
1035
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001036 // Connected.
1037 EXPECT_CALL(*mock_service0.get(), state())
1038 .WillRepeatedly(Return(Service::kStateConnected));
1039 EXPECT_CALL(*mock_service0.get(), IsConnected())
1040 .WillRepeatedly(Return(true));
1041 manager()->UpdateService(mock_service0);
1042 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
1043
Paul Stewart22aa71b2011-09-16 12:15:11 -07001044 manager()->DeregisterService(mock_service0);
1045 manager()->DeregisterService(mock_service1);
1046}
1047
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001048TEST_F(ManagerTest, SortServicesWithConnection) {
Thieu Lea20cbc22012-01-09 22:01:43 +00001049 MockMetrics mock_metrics;
1050 manager()->set_metrics(&mock_metrics);
1051
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001052 scoped_refptr<MockService> mock_service0(
1053 new NiceMock<MockService>(control_interface(),
1054 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001055 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001056 manager()));
1057 scoped_refptr<MockService> mock_service1(
1058 new NiceMock<MockService>(control_interface(),
1059 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001060 metrics(),
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001061 manager()));
1062
1063 scoped_refptr<MockConnection> mock_connection0(
1064 new NiceMock<MockConnection>(device_info_.get()));
1065 scoped_refptr<MockConnection> mock_connection1(
1066 new NiceMock<MockConnection>(device_info_.get()));
1067
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001068 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001069 manager()->RegisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001070 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001071 manager()->RegisterService(mock_service1);
1072
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001073 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1074 manager()->SortServices();
1075
1076 mock_service1->set_priority(1);
1077 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1078 manager()->SortServices();
1079
1080 mock_service1->set_priority(0);
1081 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1082 manager()->SortServices();
1083
Paul Stewartce4ec192012-03-14 12:53:46 -07001084 mock_service0->set_mock_connection(mock_connection0);
1085 mock_service1->set_mock_connection(mock_connection1);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001086
1087 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001088 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001089 manager()->SortServices();
1090
1091 mock_service1->set_priority(1);
1092 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
1093 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001094 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service1.get()));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001095 manager()->SortServices();
1096
1097 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
Thieu Lea20cbc22012-01-09 22:01:43 +00001098 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(mock_service0.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001099 mock_service1->set_mock_connection(NULL);
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001100 manager()->DeregisterService(mock_service1);
1101
Paul Stewartce4ec192012-03-14 12:53:46 -07001102 mock_service0->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001103 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001104 manager()->DeregisterService(mock_service0);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001105
1106 EXPECT_CALL(mock_metrics, NotifyDefaultServiceChanged(NULL));
1107 manager()->SortServices();
Paul Stewartc1dec4d2011-12-08 15:25:28 -08001108}
1109
Gaurav Shah435de2c2011-11-17 19:01:07 -08001110TEST_F(ManagerTest, AvailableTechnologies) {
1111 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
1112 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001113 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001114 manager(),
1115 "null4",
1116 "addr4",
1117 0));
1118 manager()->RegisterDevice(mock_devices_[0]);
1119 manager()->RegisterDevice(mock_devices_[1]);
1120 manager()->RegisterDevice(mock_devices_[2]);
1121 manager()->RegisterDevice(mock_devices_[3]);
1122
1123 ON_CALL(*mock_devices_[0].get(), technology())
1124 .WillByDefault(Return(Technology::kEthernet));
1125 ON_CALL(*mock_devices_[1].get(), technology())
1126 .WillByDefault(Return(Technology::kWifi));
1127 ON_CALL(*mock_devices_[2].get(), technology())
1128 .WillByDefault(Return(Technology::kCellular));
1129 ON_CALL(*mock_devices_[3].get(), technology())
1130 .WillByDefault(Return(Technology::kWifi));
1131
1132 set<string> expected_technologies;
1133 expected_technologies.insert(Technology::NameFromIdentifier(
1134 Technology::kEthernet));
1135 expected_technologies.insert(Technology::NameFromIdentifier(
1136 Technology::kWifi));
1137 expected_technologies.insert(Technology::NameFromIdentifier(
1138 Technology::kCellular));
1139 Error error;
1140 vector<string> technologies = manager()->AvailableTechnologies(&error);
1141
1142 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1143 ContainerEq(expected_technologies));
1144}
1145
1146TEST_F(ManagerTest, ConnectedTechnologies) {
1147 scoped_refptr<MockService> connected_service1(
1148 new NiceMock<MockService>(control_interface(),
1149 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001150 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001151 manager()));
1152 scoped_refptr<MockService> connected_service2(
1153 new NiceMock<MockService>(control_interface(),
1154 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001155 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001156 manager()));
1157 scoped_refptr<MockService> disconnected_service1(
1158 new NiceMock<MockService>(control_interface(),
1159 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001160 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001161 manager()));
1162 scoped_refptr<MockService> disconnected_service2(
1163 new NiceMock<MockService>(control_interface(),
1164 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001165 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001166 manager()));
1167
1168 ON_CALL(*connected_service1.get(), IsConnected())
1169 .WillByDefault(Return(true));
1170 ON_CALL(*connected_service2.get(), IsConnected())
1171 .WillByDefault(Return(true));
1172
1173 manager()->RegisterService(connected_service1);
1174 manager()->RegisterService(connected_service2);
1175 manager()->RegisterService(disconnected_service1);
1176 manager()->RegisterService(disconnected_service2);
1177
1178 manager()->RegisterDevice(mock_devices_[0]);
1179 manager()->RegisterDevice(mock_devices_[1]);
1180 manager()->RegisterDevice(mock_devices_[2]);
1181 manager()->RegisterDevice(mock_devices_[3]);
1182
1183 ON_CALL(*mock_devices_[0].get(), technology())
1184 .WillByDefault(Return(Technology::kEthernet));
1185 ON_CALL(*mock_devices_[1].get(), technology())
1186 .WillByDefault(Return(Technology::kWifi));
1187 ON_CALL(*mock_devices_[2].get(), technology())
1188 .WillByDefault(Return(Technology::kCellular));
1189 ON_CALL(*mock_devices_[3].get(), technology())
1190 .WillByDefault(Return(Technology::kWifi));
1191
1192 mock_devices_[0]->SelectService(connected_service1);
1193 mock_devices_[1]->SelectService(disconnected_service1);
1194 mock_devices_[2]->SelectService(disconnected_service2);
1195 mock_devices_[3]->SelectService(connected_service2);
1196
1197 set<string> expected_technologies;
1198 expected_technologies.insert(Technology::NameFromIdentifier(
1199 Technology::kEthernet));
1200 expected_technologies.insert(Technology::NameFromIdentifier(
1201 Technology::kWifi));
1202 Error error;
1203
1204 vector<string> technologies = manager()->ConnectedTechnologies(&error);
1205 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
1206 ContainerEq(expected_technologies));
1207}
1208
1209TEST_F(ManagerTest, DefaultTechnology) {
1210 scoped_refptr<MockService> connected_service(
1211 new NiceMock<MockService>(control_interface(),
1212 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001213 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001214 manager()));
1215 scoped_refptr<MockService> disconnected_service(
1216 new NiceMock<MockService>(control_interface(),
1217 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001218 metrics(),
Gaurav Shah435de2c2011-11-17 19:01:07 -08001219 manager()));
1220
1221 // Connected. WiFi.
1222 ON_CALL(*connected_service.get(), IsConnected())
1223 .WillByDefault(Return(true));
1224 ON_CALL(*connected_service.get(), state())
1225 .WillByDefault(Return(Service::kStateConnected));
1226 ON_CALL(*connected_service.get(), technology())
1227 .WillByDefault(Return(Technology::kWifi));
1228
1229 // Disconnected. Ethernet.
1230 ON_CALL(*disconnected_service.get(), technology())
1231 .WillByDefault(Return(Technology::kEthernet));
1232
1233 manager()->RegisterService(disconnected_service);
1234 Error error;
1235 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1236
1237
1238 manager()->RegisterService(connected_service);
1239 // Connected service should be brought to the front now.
1240 string expected_technology =
1241 Technology::NameFromIdentifier(Technology::kWifi);
1242 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1243}
1244
Thieu Le1271d682011-11-02 22:48:19 +00001245TEST_F(ManagerTest, DisconnectServicesOnStop) {
1246 scoped_refptr<MockService> mock_service(
1247 new NiceMock<MockService>(control_interface(),
1248 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001249 metrics(),
Thieu Le1271d682011-11-02 22:48:19 +00001250 manager()));
1251 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001252 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001253 manager()->Stop();
1254}
1255
mukesh agrawal00917ce2011-11-22 23:56:55 +00001256TEST_F(ManagerTest, UpdateServiceConnected) {
1257 scoped_refptr<MockService> mock_service(
1258 new NiceMock<MockService>(control_interface(),
1259 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001260 metrics(),
mukesh agrawal00917ce2011-11-22 23:56:55 +00001261 manager()));
1262 manager()->RegisterService(mock_service);
1263 EXPECT_FALSE(mock_service->favorite());
1264 EXPECT_FALSE(mock_service->auto_connect());
1265
Gaurav Shah435de2c2011-11-17 19:01:07 -08001266 EXPECT_CALL(*mock_service.get(), IsConnected())
1267 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001268 manager()->UpdateService(mock_service);
1269 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1270 // to mock out MakeFavorite. And mocking that out would break the
1271 // SortServices test. (crosbug.com/23370)
1272 EXPECT_TRUE(mock_service->favorite());
1273 EXPECT_TRUE(mock_service->auto_connect());
1274}
1275
Thieu Led4e9e552012-02-16 16:26:07 -08001276TEST_F(ManagerTest, UpdateServiceConnectedPersistFavorite) {
1277 // This tests the case where the user connects to a service that is
1278 // currently associated with a profile. We want to make sure that the
1279 // favorite flag is set and that the flag is saved to the current
1280 // profile.
1281 scoped_refptr<MockService> mock_service(
1282 new NiceMock<MockService>(control_interface(),
1283 dispatcher(),
1284 metrics(),
1285 manager()));
1286 manager()->RegisterService(mock_service);
1287 EXPECT_FALSE(mock_service->favorite());
1288 EXPECT_FALSE(mock_service->auto_connect());
1289
1290 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
1291 mock_service->set_profile(profile);
1292
1293 EXPECT_CALL(*mock_service.get(), IsConnected())
1294 .WillRepeatedly(Return(true));
1295 EXPECT_CALL(*mock_service.get(), SaveToCurrentProfile());
1296 manager()->UpdateService(mock_service);
1297 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1298 // to mock out MakeFavorite. And mocking that out would break the
1299 // SortServices test. (crosbug.com/23370)
1300 EXPECT_TRUE(mock_service->favorite());
1301 EXPECT_TRUE(mock_service->auto_connect());
1302}
1303
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001304TEST_F(ManagerTest, SaveSuccessfulService) {
1305 scoped_refptr<MockProfile> profile(
1306 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1307 AdoptProfile(manager(), profile);
1308 scoped_refptr<MockService> service(
1309 new NiceMock<MockService>(control_interface(),
1310 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001311 metrics(),
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001312 manager()));
1313
1314 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1315 ServiceRefPtr expect_service(service.get());
1316
1317 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1318 .WillOnce(Return(false));
1319 manager()->RegisterService(service);
1320
1321 EXPECT_CALL(*service.get(), state())
1322 .WillRepeatedly(Return(Service::kStateConnected));
1323 EXPECT_CALL(*service.get(), IsConnected())
1324 .WillRepeatedly(Return(true));
1325 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1326 .WillOnce(Return(true));
1327 manager()->UpdateService(service);
1328}
1329
Paul Stewart1b253142012-01-26 14:05:52 -08001330TEST_F(ManagerTest, EnumerateProfiles) {
1331 vector<string> profile_paths;
1332 for (size_t i = 0; i < 10; i++) {
1333 scoped_refptr<MockProfile> profile(
1334 new StrictMock<MockProfile>(control_interface(), manager(), ""));
Jason Glasgow5d8197b2012-01-27 08:37:32 -05001335 profile_paths.push_back(base::StringPrintf("/profile/%zd", i));
Paul Stewart1b253142012-01-26 14:05:52 -08001336 EXPECT_CALL(*profile.get(), GetRpcIdentifier())
1337 .WillOnce(Return(profile_paths.back()));
1338 AdoptProfile(manager(), profile);
1339 }
1340
1341 Error error;
1342 vector<string> returned_paths = manager()->EnumerateProfiles(&error);
1343 EXPECT_TRUE(error.IsSuccess());
1344 EXPECT_EQ(profile_paths.size(), returned_paths.size());
1345 for (size_t i = 0; i < profile_paths.size(); i++) {
1346 EXPECT_EQ(profile_paths[i], returned_paths[i]);
1347 }
1348}
1349
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001350TEST_F(ManagerTest, AutoConnectOnRegister) {
1351 MockServiceRefPtr service = MakeAutoConnectableService();
1352 EXPECT_CALL(*service.get(), AutoConnect());
1353 manager()->RegisterService(service);
1354 dispatcher()->DispatchPendingEvents();
1355}
1356
1357TEST_F(ManagerTest, AutoConnectOnUpdate) {
1358 MockServiceRefPtr service1 = MakeAutoConnectableService();
1359 service1->set_priority(1);
1360 MockServiceRefPtr service2 = MakeAutoConnectableService();
1361 service2->set_priority(2);
1362 manager()->RegisterService(service1);
1363 manager()->RegisterService(service2);
1364 dispatcher()->DispatchPendingEvents();
1365
1366 EXPECT_CALL(*service1.get(), AutoConnect());
1367 EXPECT_CALL(*service2.get(), state())
1368 .WillRepeatedly(Return(Service::kStateFailure));
1369 EXPECT_CALL(*service2.get(), IsFailed())
1370 .WillRepeatedly(Return(true));
1371 EXPECT_CALL(*service2.get(), IsConnected())
1372 .WillRepeatedly(Return(false));
1373 manager()->UpdateService(service2);
1374 dispatcher()->DispatchPendingEvents();
1375}
1376
1377TEST_F(ManagerTest, AutoConnectOnDeregister) {
1378 MockServiceRefPtr service1 = MakeAutoConnectableService();
1379 service1->set_priority(1);
1380 MockServiceRefPtr service2 = MakeAutoConnectableService();
1381 service2->set_priority(2);
1382 manager()->RegisterService(service1);
1383 manager()->RegisterService(service2);
1384 dispatcher()->DispatchPendingEvents();
1385
1386 EXPECT_CALL(*service1.get(), AutoConnect());
1387 manager()->DeregisterService(service2);
1388 dispatcher()->DispatchPendingEvents();
1389}
1390
Paul Stewartc681fa02012-03-02 19:40:04 -08001391TEST_F(ManagerTest, RecheckPortal) {
1392 EXPECT_CALL(*mock_devices_[0].get(), RequestPortalDetection())
1393 .WillOnce(Return(false));
1394 EXPECT_CALL(*mock_devices_[1].get(), RequestPortalDetection())
1395 .WillOnce(Return(true));
1396 EXPECT_CALL(*mock_devices_[2].get(), RequestPortalDetection())
1397 .Times(0);
1398
1399 manager()->RegisterDevice(mock_devices_[0]);
1400 manager()->RegisterDevice(mock_devices_[1]);
1401 manager()->RegisterDevice(mock_devices_[2]);
1402
1403 manager()->RecheckPortal(NULL);
1404}
1405
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001406TEST_F(ManagerTest, GetDefaultService) {
1407 EXPECT_FALSE(manager()->GetDefaultService().get());
1408
1409 scoped_refptr<MockService> mock_service(
1410 new NiceMock<MockService>(control_interface(),
1411 dispatcher(),
1412 metrics(),
1413 manager()));
1414
1415 manager()->RegisterService(mock_service);
1416 EXPECT_FALSE(manager()->GetDefaultService().get());
1417
1418 scoped_refptr<MockConnection> mock_connection(
1419 new NiceMock<MockConnection>(device_info_.get()));
Paul Stewartce4ec192012-03-14 12:53:46 -07001420 mock_service->set_mock_connection(mock_connection);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001421 EXPECT_EQ(mock_service.get(), manager()->GetDefaultService().get());
1422
Paul Stewartce4ec192012-03-14 12:53:46 -07001423 mock_service->set_mock_connection(NULL);
Paul Stewarte2bad7c2012-03-14 08:55:33 -07001424 manager()->DeregisterService(mock_service);
1425}
1426
Paul Stewart13ed2252012-03-21 12:52:46 -07001427TEST_F(ManagerTest, GetServiceWithGUID) {
1428 scoped_refptr<MockService> mock_service0(
1429 new NiceMock<MockService>(control_interface(),
1430 dispatcher(),
1431 metrics(),
1432 manager()));
1433
1434 scoped_refptr<MockService> mock_service1(
1435 new NiceMock<MockService>(control_interface(),
1436 dispatcher(),
1437 metrics(),
1438 manager()));
1439
1440 manager()->RegisterService(mock_service0);
1441 manager()->RegisterService(mock_service1);
1442
1443 const string kGUID0 = "GUID0";
1444 const string kGUID1 = "GUID1";
1445
1446 {
1447 Error error;
1448 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1449 EXPECT_FALSE(error.IsSuccess());
1450 EXPECT_FALSE(service);
1451 }
1452
1453 KeyValueStore args;
1454 args.SetString(flimflam::kGuidProperty, kGUID1);
1455
1456 {
1457 Error error;
1458 ServiceRefPtr service = manager()->GetService(args, &error);
1459 EXPECT_EQ(Error::kInvalidArguments, error.type());
1460 EXPECT_FALSE(service);
1461 }
1462
1463 mock_service0->set_guid(kGUID0);
1464 mock_service1->set_guid(kGUID1);
1465
1466 {
1467 Error error;
1468 ServiceRefPtr service = manager()->GetServiceWithGUID(kGUID0, &error);
1469 EXPECT_TRUE(error.IsSuccess());
1470 EXPECT_EQ(mock_service0.get(), service.get());
1471 }
1472
1473 {
1474 Error error;
1475 ServiceRefPtr service = manager()->GetService(args, &error);
1476 EXPECT_TRUE(error.IsSuccess());
1477 EXPECT_EQ(mock_service1.get(), service.get());
1478 }
1479
1480 manager()->DeregisterService(mock_service0);
1481 manager()->DeregisterService(mock_service1);
1482}
1483
Chris Masone9be4a9d2011-05-16 15:44:09 -07001484} // namespace shill