blob: d4f54b1c1f190134ac4704d718b63539114f75c8 [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>
Paul Stewart5dc40aa2011-10-28 19:43:43 -070012#include <base/memory/scoped_temp_dir.h>
Chris Masone6791a432011-07-12 13:23:19 -070013#include <base/stl_util-inl.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"
31#include "shill/mock_profile.h"
Chris Masone9be4a9d2011-05-16 15:44:09 -070032#include "shill/mock_service.h"
Chris Masoneb9c00592011-10-06 13:10:39 -070033#include "shill/mock_store.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070034#include "shill/mock_wifi.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035#include "shill/property_store_unittest.h"
Chris Masone6515aab2011-10-12 16:19:09 -070036#include "shill/service_under_test.h"
mukesh agrawal7a4e4002011-09-06 11:26:05 -070037#include "shill/wifi_service.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070038
39using std::map;
Chris Masone6791a432011-07-12 13:23:19 -070040using std::set;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070041using std::string;
42using std::vector;
43
Chris Masone9be4a9d2011-05-16 15:44:09 -070044namespace shill {
Chris Masone9be4a9d2011-05-16 15:44:09 -070045using ::testing::_;
Chris Masone6515aab2011-10-12 16:19:09 -070046using ::testing::AnyNumber;
Gaurav Shah435de2c2011-11-17 19:01:07 -080047using ::testing::ContainerEq;
Paul Stewart22aa71b2011-09-16 12:15:11 -070048using ::testing::Ne;
Chris Masone9be4a9d2011-05-16 15:44:09 -070049using ::testing::NiceMock;
50using ::testing::Return;
Gaurav Shah435de2c2011-11-17 19:01:07 -080051using ::testing::StrEq;
Paul Stewart3d9bcf52011-12-12 15:02:22 -080052using ::testing::StrictMock;
Chris Masone9d779932011-08-25 16:33:41 -070053using ::testing::Test;
Chris Masone9be4a9d2011-05-16 15:44:09 -070054
Chris Masone3bd3c8c2011-06-13 08:20:26 -070055class ManagerTest : public PropertyStoreTest {
Chris Masone9be4a9d2011-05-16 15:44:09 -070056 public:
Chris Masone3c3f6a12011-07-01 10:01:41 -070057 ManagerTest()
Paul Stewart22aa71b2011-09-16 12:15:11 -070058 : mock_wifi_(new NiceMock<MockWiFi>(control_interface(),
mukesh agrawal7a4e4002011-09-06 11:26:05 -070059 dispatcher(),
60 manager(),
61 "wifi0",
62 "addr4",
Paul Stewartc1dec4d2011-12-08 15:25:28 -080063 4)),
64 device_info_(new NiceMock<MockDeviceInfo>(
65 control_interface(),
66 reinterpret_cast<EventDispatcher*>(NULL),
67 reinterpret_cast<Manager*>(NULL))),
68 manager_adaptor_(new NiceMock<ManagerMockAdaptor>()) {
Paul Stewart22aa71b2011-09-16 12:15:11 -070069 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
70 dispatcher(),
71 manager(),
72 "null0",
73 "addr0",
74 0));
75 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
76 dispatcher(),
77 manager(),
78 "null1",
79 "addr1",
80 1));
81 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
82 dispatcher(),
83 manager(),
84 "null2",
85 "addr2",
86 2));
Gaurav Shah435de2c2011-11-17 19:01:07 -080087 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
88 dispatcher(),
89 manager(),
90 "null3",
91 "addr3",
92 3));
Paul Stewart5dc40aa2011-10-28 19:43:43 -070093 manager()->connect_profiles_to_rpc_ = false;
Paul Stewartc1dec4d2011-12-08 15:25:28 -080094
95 // Replace the manager's adaptor with a quieter one, and one
96 // we can do EXPECT*() against. Passes ownership.
97 manager()->adaptor_.reset(manager_adaptor_);
Chris Masone3c3f6a12011-07-01 10:01:41 -070098 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070099 virtual ~ManagerTest() {}
Chris Masone9be4a9d2011-05-16 15:44:09 -0700100
Paul Stewartfdd16072011-09-16 12:41:35 -0700101 bool IsDeviceRegistered(const DeviceRefPtr &device,
102 Technology::Identifier tech) {
Chris Masonec1e50412011-06-07 13:04:53 -0700103 vector<DeviceRefPtr> devices;
Chris Masone9d779932011-08-25 16:33:41 -0700104 manager()->FilterByTechnology(tech, &devices);
Chris Masone2b105542011-06-22 10:58:09 -0700105 return (devices.size() == 1 && devices[0].get() == device.get());
Chris Masone9be4a9d2011-05-16 15:44:09 -0700106 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700107 bool ServiceOrderIs(ServiceRefPtr svc1, ServiceRefPtr svc2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700108
Paul Stewarta849a3d2011-11-03 05:54:09 -0700109 void AdoptProfile(Manager *manager, ProfileRefPtr profile) {
110 manager->profiles_.push_back(profile);
111 }
112
Chris Masone6515aab2011-10-12 16:19:09 -0700113 Profile *CreateProfileForManager(Manager *manager, GLib *glib) {
114 Profile::Identifier id("rather", "irrelevant");
115 scoped_ptr<Profile> profile(new Profile(control_interface(),
116 manager,
117 id,
118 "",
119 false));
120 FilePath final_path(storage_path());
121 final_path = final_path.Append("test.profile");
122 scoped_ptr<KeyFileStore> storage(new KeyFileStore(glib));
123 storage->set_path(final_path);
124 if (!storage->Open())
125 return NULL;
126 profile->set_storage(storage.release()); // Passes ownership.
127 return profile.release();
128 }
129
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700130 bool CreateBackingStoreForService(ScopedTempDir *temp_dir,
131 const string &profile_identifier,
132 const string &service_name) {
133 GLib glib;
134 KeyFileStore store(&glib);
135 store.set_path(temp_dir->path().Append(profile_identifier + ".profile"));
136 return store.Open() &&
137 store.SetString(service_name, "rather", "irrelevant") &&
138 store.Close();
139 }
140
141 Error::Type TestCreateProfile(Manager *manager, const string &name) {
142 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800143 string path;
144 manager->CreateProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700145 return error.type();
146 }
147
148 Error::Type TestPopAnyProfile(Manager *manager) {
149 Error error;
150 manager->PopAnyProfile(&error);
151 return error.type();
152 }
153
154 Error::Type TestPopProfile(Manager *manager, const string &name) {
155 Error error;
156 manager->PopProfile(name, &error);
157 return error.type();
158 }
159
160 Error::Type TestPushProfile(Manager *manager, const string &name) {
161 Error error;
Paul Stewart19c871d2011-12-15 16:10:13 -0800162 string path;
163 manager->PushProfile(name, &path, &error);
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700164 return error.type();
165 }
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000166
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700167 protected:
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000168 typedef scoped_refptr<MockService> MockServiceRefPtr;
169
170 MockServiceRefPtr MakeAutoConnectableService() {
171 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
172 dispatcher(),
173 manager());
174 service->MakeFavorite();
175 service->set_connectable(true);
176 return service;
177 }
178
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700179 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700180 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800181 scoped_ptr<MockDeviceInfo> device_info_;
182
183 // This pointer is owned by the manager, and only tracked here for EXPECT*()
184 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700185};
186
Paul Stewart22aa71b2011-09-16 12:15:11 -0700187bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
188 return (svc0.get() == manager()->services_[0].get() &&
189 svc1.get() == manager()->services_[1].get());
190}
191
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700192TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700193 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
194 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700195}
196
Chris Masone9be4a9d2011-05-16 15:44:09 -0700197TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700198 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700199 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700200 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700201 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700202 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700203 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700204
Paul Stewart22aa71b2011-09-16 12:15:11 -0700205 manager()->RegisterDevice(mock_devices_[0]);
206 manager()->RegisterDevice(mock_devices_[1]);
207 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700208
Paul Stewart22aa71b2011-09-16 12:15:11 -0700209 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
210 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
211 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700212}
213
Paul Stewarta41e38d2011-11-11 07:47:29 -0800214TEST_F(ManagerTest, DeviceRegistrationAndStart) {
215 manager()->running_ = true;
216 mock_devices_[0]->powered_ = true;
217 mock_devices_[1]->powered_ = false;
218 EXPECT_CALL(*mock_devices_[0].get(), Start())
219 .Times(1);
220 EXPECT_CALL(*mock_devices_[1].get(), Start())
221 .Times(0);
222 manager()->RegisterDevice(mock_devices_[0]);
223 manager()->RegisterDevice(mock_devices_[1]);
224}
225
226TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
227 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
228 DeviceRefPtr device_ref(mock_devices_[0].get());
229 AdoptProfile(manager(), profile); // Passes ownership.
230 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
231 EXPECT_CALL(*profile, Save());
232 manager()->RegisterDevice(mock_devices_[0]);
233}
234
Chris Masone9be4a9d2011-05-16 15:44:09 -0700235TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700236 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700237 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700238 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700239 .WillByDefault(Return(true));
240
Gaurav Shah435de2c2011-11-17 19:01:07 -0800241 manager()->RegisterDevice(mock_devices_[0]);
242 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700243
Paul Stewart22aa71b2011-09-16 12:15:11 -0700244 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
245 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700246
Paul Stewart22aa71b2011-09-16 12:15:11 -0700247 EXPECT_CALL(*mock_devices_[0].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800248 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700249 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700250
Paul Stewart22aa71b2011-09-16 12:15:11 -0700251 EXPECT_CALL(*mock_devices_[1].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800252 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700253 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700254}
255
256TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700257 // It's much easier and safer to use a real GLib for this test.
258 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700259 Manager manager(control_interface(),
260 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700261 &glib,
262 run_path(),
263 storage_path(),
264 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700265 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
266 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700267 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700268
Chris Masone9be4a9d2011-05-16 15:44:09 -0700269 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700270 new NiceMock<MockService>(control_interface(),
271 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700272 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700273 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700274 new NiceMock<MockService>(control_interface(),
275 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700276 &manager));
mukesh agrawal51a7e932011-07-27 16:18:26 -0700277 string service1_name(mock_service->UniqueName());
278 string service2_name(mock_service2->UniqueName());
279
280 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
281 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700282 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700283 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700284 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700285 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700286 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700287
Chris Masone9d779932011-08-25 16:33:41 -0700288 manager.RegisterService(mock_service);
289 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700290
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800291 Error error;
292 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700293 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700294 EXPECT_EQ(2, ids.size());
295 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
296 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700297
Chris Masone9d779932011-08-25 16:33:41 -0700298 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
299 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
300
301 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700302}
303
Chris Masone6515aab2011-10-12 16:19:09 -0700304TEST_F(ManagerTest, RegisterKnownService) {
305 // It's much easier and safer to use a real GLib for this test.
306 GLib glib;
307 Manager manager(control_interface(),
308 dispatcher(),
309 &glib,
310 run_path(),
311 storage_path(),
312 string());
313 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
314 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700315 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700316 {
317 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
318 dispatcher(),
319 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700320 ASSERT_TRUE(profile->AdoptService(service1));
321 ASSERT_TRUE(profile->ContainsService(service1));
322 } // Force destruction of service1.
323
324 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
325 dispatcher(),
326 &manager));
327 manager.RegisterService(service2);
328 EXPECT_EQ(service2->profile().get(), profile.get());
329 manager.Stop();
330}
331
332TEST_F(ManagerTest, RegisterUnknownService) {
333 // It's much easier and safer to use a real GLib for this test.
334 GLib glib;
335 Manager manager(control_interface(),
336 dispatcher(),
337 &glib,
338 run_path(),
339 storage_path(),
340 string());
341 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
342 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700343 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700344 {
345 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
346 dispatcher(),
347 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700348 ASSERT_TRUE(profile->AdoptService(service1));
349 ASSERT_TRUE(profile->ContainsService(service1));
350 } // Force destruction of service1.
351 scoped_refptr<MockService> mock_service2(
352 new NiceMock<MockService>(control_interface(),
353 dispatcher(),
354 &manager));
355 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
356 .WillRepeatedly(Return(mock_service2->UniqueName()));
357 manager.RegisterService(mock_service2);
358 EXPECT_NE(mock_service2->profile().get(), profile.get());
359 manager.Stop();
360}
361
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000362TEST_F(ManagerTest, DeregisterUnregisteredService) {
363 // WiFi assumes that it can deregister a service that is not
364 // registered. (E.g. a hidden service can be deregistered when it
365 // loses its last endpoint, and again when WiFi is Stop()-ed.)
366 //
367 // So test that doing so doesn't cause a crash.
368 MockServiceRefPtr service = new NiceMock<MockService>(control_interface(),
369 dispatcher(),
370 manager());
371 manager()->DeregisterService(service);
372}
373
Chris Masonea8a2c252011-06-27 22:16:30 -0700374TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700375 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700376 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700377 map<string, ::DBus::Variant> props;
378 Error error(Error::kInvalidProperty, "");
379 {
380 ::DBus::Error dbus_error;
381 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700382 manager()->mutable_store()->SetStringProperty(
383 flimflam::kCheckPortalListProperty,
384 expected,
385 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700386 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700387 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
388 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
389 expected);
390 }
391 {
392 ::DBus::Error dbus_error;
393 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700394 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
395 expected,
396 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700397 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700398 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
399 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
400 expected);
401 }
402}
403
Chris Masone3c3f6a12011-07-01 10:01:41 -0700404TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700405 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700406 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800407 manager()->RegisterDevice(mock_devices_[0]);
408 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700409 {
410 map<string, ::DBus::Variant> props;
411 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700412 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700413 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
414 Strings devices =
415 props[flimflam::kDevicesProperty].operator vector<string>();
416 EXPECT_EQ(2, devices.size());
417 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700418}
419
Chris Masone6791a432011-07-12 13:23:19 -0700420TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700421 Manager manager(control_interface(),
422 dispatcher(),
Chris Masone6515aab2011-10-12 16:19:09 -0700423 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700424 run_path(),
425 storage_path(),
426 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700427 scoped_refptr<MockService> s2(new MockService(control_interface(),
428 dispatcher(),
429 &manager));
430 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700431 {
Chris Masone6515aab2011-10-12 16:19:09 -0700432 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700433 ProfileRefPtr profile(
434 new Profile(control_interface(), &manager, id, "", false));
435 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700436 // Say we don't have |s2| the first time asked, then that we do.
437 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
438 .WillOnce(Return(false))
439 .WillRepeatedly(Return(true));
440 EXPECT_CALL(*storage, Flush())
441 .Times(AnyNumber())
442 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700443 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700444 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700445 }
Chris Masone6515aab2011-10-12 16:19:09 -0700446 // Create a profile that already has |s2| in it.
447 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
448 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700449
Chris Masone6515aab2011-10-12 16:19:09 -0700450 // Now, move the Service |s2| to another profile.
451 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
452 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700453
454 // Force destruction of the original Profile, to ensure that the Service
455 // is kept alive and populated with data.
456 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700457 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700458 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700459}
460
Paul Stewart1b1a7f22012-01-06 16:24:06 -0800461TEST_F(ManagerTest, SetProfileForService) {
462 scoped_refptr<MockProfile> profile0(
463 new MockProfile(control_interface(), manager(), ""));
464 string profile_name0("profile0");
465 EXPECT_CALL(*profile0, GetRpcIdentifier())
466 .WillRepeatedly(Return(profile_name0));
467 AdoptProfile(manager(), profile0);
468 scoped_refptr<MockService> service(new MockService(control_interface(),
469 dispatcher(),
470 manager()));
471 service->set_profile(profile0);
472
473 {
474 Error error;
475 manager()->SetProfileForService(service, "foo", &error);
476 EXPECT_EQ(Error::kInvalidArguments, error.type());
477 EXPECT_EQ("Unknown Profile requested for Service", error.message());
478 }
479
480 {
481 Error error;
482 manager()->SetProfileForService(service, profile_name0, &error);
483 EXPECT_EQ(Error::kInvalidArguments, error.type());
484 EXPECT_EQ("Service is already connected to this profile", error.message());
485 }
486
487 scoped_refptr<MockProfile> profile1(
488 new MockProfile(control_interface(), manager(), ""));
489 string profile_name1("profile1");
490 EXPECT_CALL(*profile1, GetRpcIdentifier())
491 .WillRepeatedly(Return(profile_name1));
492 AdoptProfile(manager(), profile1);
493
494 {
495 Error error;
496 EXPECT_CALL(*profile1, AdoptService(_))
497 .WillOnce(Return(true));
498 EXPECT_CALL(*profile0, AbandonService(_))
499 .WillOnce(Return(true));
500 manager()->SetProfileForService(service, profile_name1, &error);
501 EXPECT_TRUE(error.IsSuccess());
502 }
503}
504
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700505TEST_F(ManagerTest, CreateProfile) {
506 // It's much easier to use real Glib here since we want the storage
507 // side-effects.
508 GLib glib;
509 ScopedTempDir temp_dir;
510 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
511
512 Manager manager(control_interface(),
513 dispatcher(),
514 &glib,
515 run_path(),
516 storage_path(),
517 temp_dir.path().value());
518
519 // Invalid name should be rejected.
520 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
521
522 // Valid name is still rejected because we can't create a profile
523 // that doesn't have a user component. Such profile names are
524 // reserved for the single DefaultProfile the manager creates
525 // at startup.
526 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, "valid"));
527
528 // We should succeed in creating a valid user profile.
529 const char kProfile[] = "~user/profile";
530 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
531
532 // We should fail in creating it a second time (already exists).
533 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
534}
535
536TEST_F(ManagerTest, PushPopProfile) {
537 // It's much easier to use real Glib in creating a Manager for this
538 // test here since we want the storage side-effects.
539 GLib glib;
540 ScopedTempDir temp_dir;
541 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
542 Manager manager(control_interface(),
543 dispatcher(),
544 &glib,
545 run_path(),
546 storage_path(),
547 temp_dir.path().value());
548
549 // Pushing an invalid profile should fail.
550 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
551
552 // Pushing a default profile name should fail.
553 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, "default"));
554
555 const char kProfile0[] = "~user/profile0";
556 const char kProfile1[] = "~user/profile1";
557
558 // Create a couple of profiles.
559 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
560 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
561
562 // Push these profiles on the stack.
563 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
564 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
565
566 // Pushing a profile a second time should fail.
567 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
568 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
569
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800570 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700571 // Active profile should be the last one we pushed.
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800572 EXPECT_EQ(kProfile1, "~" + manager.GetActiveProfileName(&error));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700573
574 // Make sure a profile name that doesn't exist fails.
575 const char kProfile2Id[] = "profile2";
576 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
577 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
578
579 // Create a new service, with a specific storage name.
580 scoped_refptr<MockService> service(
581 new NiceMock<MockService>(control_interface(),
582 dispatcher(),
583 &manager));
584 const char kServiceName[] = "service_storage_name";
585 EXPECT_CALL(*service.get(), GetStorageIdentifier())
586 .WillRepeatedly(Return(kServiceName));
587 EXPECT_CALL(*service.get(), Load(_))
588 .WillRepeatedly(Return(true));
589
590 // Add this service to the manager -- it should end up in the ephemeral
591 // profile.
592 manager.RegisterService(service);
593 ASSERT_EQ(manager.ephemeral_profile_, service->profile());
594
595 // Create storage for a profile that contains the service storage name.
596 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
597 kServiceName));
598
599 // When we push the profile, the service should move away from the
600 // ephemeral profile to this new profile since it has an entry for
601 // this service.
602 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
603 EXPECT_NE(manager.ephemeral_profile_, service->profile());
604 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
605
606 // Insert another profile that should supersede ownership of the service.
607 const char kProfile3Id[] = "profile3";
608 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
609 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
610 kServiceName));
611 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
612 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
613
614 // Popping an invalid profile name should fail.
615 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
616
617 // Popping an profile that is not at the top of the stack should fail.
618 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
619
620 // Popping the top profile should succeed.
621 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
622
623 // Moreover the service should have switched profiles to profile 2.
624 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
625
626 // Popping the top profile should succeed.
627 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
628
629 // The service should now revert to the ephemeral profile.
630 EXPECT_EQ(manager.ephemeral_profile_, service->profile());
631
632 // Pop the remaining two services off the stack.
633 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
634 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
635
636 // Next pop should fail with "stack is empty".
637 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
638}
639
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700640TEST_F(ManagerTest, Dispatch) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700641 {
642 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700643 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700644 flimflam::kOfflineModeProperty,
645 PropertyStoreTest::kBoolV,
646 &error));
647 }
648 {
649 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700650 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700651 flimflam::kCountryProperty,
652 PropertyStoreTest::kStringV,
653 &error));
654 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700655 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700656 {
657 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700658 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700659 flimflam::kCountryProperty,
660 PropertyStoreTest::kBoolV,
661 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700662 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700663 }
664 {
665 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700666 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700667 flimflam::kOfflineModeProperty,
668 PropertyStoreTest::kStringV,
669 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700670 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700671 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700672 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700673 {
674 ::DBus::Error error;
675 EXPECT_FALSE(DBusAdaptor::DispatchOnType(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700676 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700677 flimflam::kEnabledTechnologiesProperty,
678 PropertyStoreTest::kStringsV,
679 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700680 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700681 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700682}
683
mukesh agrawal32399322011-09-01 10:53:43 -0700684TEST_F(ManagerTest, RequestScan) {
685 {
686 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700687 manager()->RegisterDevice(mock_devices_[0].get());
688 manager()->RegisterDevice(mock_devices_[1].get());
689 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700690 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700691 EXPECT_CALL(*mock_devices_[0], Scan(_));
692 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700693 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700694 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -0700695 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700696 }
697
698 {
699 Error error;
Chris Masone9d779932011-08-25 16:33:41 -0700700 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700701 EXPECT_EQ(Error::kInvalidArguments, error.type());
702 }
703}
704
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700705TEST_F(ManagerTest, GetWifiServiceNoDevice) {
706 KeyValueStore args;
707 Error e;
708 manager()->GetWifiService(args, &e);
709 EXPECT_EQ(Error::kInvalidArguments, e.type());
710 EXPECT_EQ("no wifi devices available", e.message());
711}
712
713TEST_F(ManagerTest, GetWifiService) {
714 KeyValueStore args;
715 Error e;
716 WiFiServiceRefPtr wifi_service;
717
718 manager()->RegisterDevice(mock_wifi_);
719 EXPECT_CALL(*mock_wifi_, GetService(_, _))
720 .WillRepeatedly(Return(wifi_service));
721 manager()->GetWifiService(args, &e);
722}
723
Paul Stewart22aa71b2011-09-16 12:15:11 -0700724TEST_F(ManagerTest, TechnologyOrder) {
725 Error error;
726 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
727 string(flimflam::kTypeWifi), &error);
728 ASSERT_TRUE(error.IsSuccess());
729 EXPECT_EQ(manager()->GetTechnologyOrder(),
730 string(flimflam::kTypeEthernet) + "," +
731 string(flimflam::kTypeWifi));
732
733 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
734 string(flimflam::kTypeWifi), &error);
735 ASSERT_FALSE(error.IsSuccess());
736 EXPECT_EQ(Error::kInvalidArguments, error.type());
737 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
738 string(flimflam::kTypeWifi),
739 manager()->GetTechnologyOrder());
740}
741
742TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +0000743 // TODO(quiche): Some of these tests would probably fit better in
744 // service_unittest, since the actual comparison of Services is
745 // implemented in Service. (crosbug.com/23370)
746
Paul Stewart22aa71b2011-09-16 12:15:11 -0700747 scoped_refptr<MockService> mock_service0(
748 new NiceMock<MockService>(control_interface(),
749 dispatcher(),
750 manager()));
751 scoped_refptr<MockService> mock_service1(
752 new NiceMock<MockService>(control_interface(),
753 dispatcher(),
754 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700755
756 manager()->RegisterService(mock_service0);
757 manager()->RegisterService(mock_service1);
758
759 // Services should already be sorted by UniqueName
760 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
761
762 // Asking explictly to sort services should not change anything
763 manager()->SortServices();
764 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
765
766 // Two otherwise equal services should be reordered by strength
767 mock_service1->set_strength(1);
768 manager()->UpdateService(mock_service1);
769 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
770
771 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -0700772 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700773 manager()->UpdateService(mock_service0);
774 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
775
776 // Technology
777 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
778 .WillRepeatedly(Return(true));
779 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
780 .WillRepeatedly(Return(true));
781 // NB: Redefine default (false) return values so we don't use the default rule
782 // which makes the logs noisier
783 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
784 .WillRepeatedly(Return(false));
785 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
786 .WillRepeatedly(Return(false));
787
788 Error error;
789 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
790 string(flimflam::kTypeWifi), &error);
791 EXPECT_TRUE(error.IsSuccess());
792 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
793
794 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
795 string(flimflam::kTypeEthernet), &error);
796 EXPECT_TRUE(error.IsSuccess());
797 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
798
Gaurav Shah435de2c2011-11-17 19:01:07 -0800799 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700800 mock_service0->set_priority(1);
801 manager()->UpdateService(mock_service0);
802 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
803
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000804 // Favorite.
mukesh agrawal00917ce2011-11-22 23:56:55 +0000805 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700806 manager()->UpdateService(mock_service1);
807 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
808
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000809 // Auto-connect.
810 mock_service0->set_auto_connect(true);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700811 manager()->UpdateService(mock_service0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000812 mock_service1->set_auto_connect(false);
813 manager()->UpdateService(mock_service1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700814 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
815
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000816 // Connectable.
817 mock_service1->set_connectable(true);
818 manager()->UpdateService(mock_service1);
819 mock_service0->set_connectable(false);
820 manager()->UpdateService(mock_service0);
821 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
822
823 // IsFailed.
824 EXPECT_CALL(*mock_service0.get(), state())
825 .WillRepeatedly(Return(Service::kStateIdle));
826 EXPECT_CALL(*mock_service0.get(), IsFailed())
827 .WillRepeatedly(Return(false));
828 manager()->UpdateService(mock_service0);
829 EXPECT_CALL(*mock_service0.get(), state())
830 .WillRepeatedly(Return(Service::kStateFailure));
831 EXPECT_CALL(*mock_service1.get(), IsFailed())
832 .WillRepeatedly(Return(true));
833 manager()->UpdateService(mock_service1);
834 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
835
836 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700837 EXPECT_CALL(*mock_service1.get(), state())
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000838 .WillRepeatedly(Return(Service::kStateAssociating));
839 EXPECT_CALL(*mock_service1.get(), IsConnecting())
Gaurav Shah435de2c2011-11-17 19:01:07 -0800840 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700841 manager()->UpdateService(mock_service1);
842 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
843
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000844 // Connected.
845 EXPECT_CALL(*mock_service0.get(), state())
846 .WillRepeatedly(Return(Service::kStateConnected));
847 EXPECT_CALL(*mock_service0.get(), IsConnected())
848 .WillRepeatedly(Return(true));
849 manager()->UpdateService(mock_service0);
850 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
851
Paul Stewart22aa71b2011-09-16 12:15:11 -0700852 manager()->DeregisterService(mock_service0);
853 manager()->DeregisterService(mock_service1);
854}
855
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800856TEST_F(ManagerTest, SortServicesWithConnection) {
857 scoped_refptr<MockService> mock_service0(
858 new NiceMock<MockService>(control_interface(),
859 dispatcher(),
860 manager()));
861 scoped_refptr<MockService> mock_service1(
862 new NiceMock<MockService>(control_interface(),
863 dispatcher(),
864 manager()));
865
866 scoped_refptr<MockConnection> mock_connection0(
867 new NiceMock<MockConnection>(device_info_.get()));
868 scoped_refptr<MockConnection> mock_connection1(
869 new NiceMock<MockConnection>(device_info_.get()));
870
871 manager()->RegisterService(mock_service0);
872 manager()->RegisterService(mock_service1);
873
874 mock_service0->connection_ = mock_connection0;
875 mock_service1->connection_ = mock_connection1;
876
877 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
878 manager()->SortServices();
879
880 mock_service1->set_priority(1);
881 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
882 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
883 manager()->SortServices();
884
885 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
886 mock_service1->connection_ = NULL;
887 manager()->DeregisterService(mock_service1);
888
889 mock_service0->connection_ = NULL;
890 manager()->DeregisterService(mock_service0);
891}
892
Gaurav Shah435de2c2011-11-17 19:01:07 -0800893TEST_F(ManagerTest, AvailableTechnologies) {
894 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
895 dispatcher(),
896 manager(),
897 "null4",
898 "addr4",
899 0));
900 manager()->RegisterDevice(mock_devices_[0]);
901 manager()->RegisterDevice(mock_devices_[1]);
902 manager()->RegisterDevice(mock_devices_[2]);
903 manager()->RegisterDevice(mock_devices_[3]);
904
905 ON_CALL(*mock_devices_[0].get(), technology())
906 .WillByDefault(Return(Technology::kEthernet));
907 ON_CALL(*mock_devices_[1].get(), technology())
908 .WillByDefault(Return(Technology::kWifi));
909 ON_CALL(*mock_devices_[2].get(), technology())
910 .WillByDefault(Return(Technology::kCellular));
911 ON_CALL(*mock_devices_[3].get(), technology())
912 .WillByDefault(Return(Technology::kWifi));
913
914 set<string> expected_technologies;
915 expected_technologies.insert(Technology::NameFromIdentifier(
916 Technology::kEthernet));
917 expected_technologies.insert(Technology::NameFromIdentifier(
918 Technology::kWifi));
919 expected_technologies.insert(Technology::NameFromIdentifier(
920 Technology::kCellular));
921 Error error;
922 vector<string> technologies = manager()->AvailableTechnologies(&error);
923
924 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
925 ContainerEq(expected_technologies));
926}
927
928TEST_F(ManagerTest, ConnectedTechnologies) {
929 scoped_refptr<MockService> connected_service1(
930 new NiceMock<MockService>(control_interface(),
931 dispatcher(),
932 manager()));
933 scoped_refptr<MockService> connected_service2(
934 new NiceMock<MockService>(control_interface(),
935 dispatcher(),
936 manager()));
937 scoped_refptr<MockService> disconnected_service1(
938 new NiceMock<MockService>(control_interface(),
939 dispatcher(),
940 manager()));
941 scoped_refptr<MockService> disconnected_service2(
942 new NiceMock<MockService>(control_interface(),
943 dispatcher(),
944 manager()));
945
946 ON_CALL(*connected_service1.get(), IsConnected())
947 .WillByDefault(Return(true));
948 ON_CALL(*connected_service2.get(), IsConnected())
949 .WillByDefault(Return(true));
950
951 manager()->RegisterService(connected_service1);
952 manager()->RegisterService(connected_service2);
953 manager()->RegisterService(disconnected_service1);
954 manager()->RegisterService(disconnected_service2);
955
956 manager()->RegisterDevice(mock_devices_[0]);
957 manager()->RegisterDevice(mock_devices_[1]);
958 manager()->RegisterDevice(mock_devices_[2]);
959 manager()->RegisterDevice(mock_devices_[3]);
960
961 ON_CALL(*mock_devices_[0].get(), technology())
962 .WillByDefault(Return(Technology::kEthernet));
963 ON_CALL(*mock_devices_[1].get(), technology())
964 .WillByDefault(Return(Technology::kWifi));
965 ON_CALL(*mock_devices_[2].get(), technology())
966 .WillByDefault(Return(Technology::kCellular));
967 ON_CALL(*mock_devices_[3].get(), technology())
968 .WillByDefault(Return(Technology::kWifi));
969
970 mock_devices_[0]->SelectService(connected_service1);
971 mock_devices_[1]->SelectService(disconnected_service1);
972 mock_devices_[2]->SelectService(disconnected_service2);
973 mock_devices_[3]->SelectService(connected_service2);
974
975 set<string> expected_technologies;
976 expected_technologies.insert(Technology::NameFromIdentifier(
977 Technology::kEthernet));
978 expected_technologies.insert(Technology::NameFromIdentifier(
979 Technology::kWifi));
980 Error error;
981
982 vector<string> technologies = manager()->ConnectedTechnologies(&error);
983 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
984 ContainerEq(expected_technologies));
985}
986
987TEST_F(ManagerTest, DefaultTechnology) {
988 scoped_refptr<MockService> connected_service(
989 new NiceMock<MockService>(control_interface(),
990 dispatcher(),
991 manager()));
992 scoped_refptr<MockService> disconnected_service(
993 new NiceMock<MockService>(control_interface(),
994 dispatcher(),
995 manager()));
996
997 // Connected. WiFi.
998 ON_CALL(*connected_service.get(), IsConnected())
999 .WillByDefault(Return(true));
1000 ON_CALL(*connected_service.get(), state())
1001 .WillByDefault(Return(Service::kStateConnected));
1002 ON_CALL(*connected_service.get(), technology())
1003 .WillByDefault(Return(Technology::kWifi));
1004
1005 // Disconnected. Ethernet.
1006 ON_CALL(*disconnected_service.get(), technology())
1007 .WillByDefault(Return(Technology::kEthernet));
1008
1009 manager()->RegisterService(disconnected_service);
1010 Error error;
1011 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
1012
1013
1014 manager()->RegisterService(connected_service);
1015 // Connected service should be brought to the front now.
1016 string expected_technology =
1017 Technology::NameFromIdentifier(Technology::kWifi);
1018 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
1019}
1020
Thieu Le1271d682011-11-02 22:48:19 +00001021TEST_F(ManagerTest, DisconnectServicesOnStop) {
1022 scoped_refptr<MockService> mock_service(
1023 new NiceMock<MockService>(control_interface(),
1024 dispatcher(),
1025 manager()));
1026 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +00001027 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +00001028 manager()->Stop();
1029}
1030
mukesh agrawal00917ce2011-11-22 23:56:55 +00001031TEST_F(ManagerTest, UpdateServiceConnected) {
1032 scoped_refptr<MockService> mock_service(
1033 new NiceMock<MockService>(control_interface(),
1034 dispatcher(),
1035 manager()));
1036 manager()->RegisterService(mock_service);
1037 EXPECT_FALSE(mock_service->favorite());
1038 EXPECT_FALSE(mock_service->auto_connect());
1039
Gaurav Shah435de2c2011-11-17 19:01:07 -08001040 EXPECT_CALL(*mock_service.get(), IsConnected())
1041 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +00001042 manager()->UpdateService(mock_service);
1043 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
1044 // to mock out MakeFavorite. And mocking that out would break the
1045 // SortServices test. (crosbug.com/23370)
1046 EXPECT_TRUE(mock_service->favorite());
1047 EXPECT_TRUE(mock_service->auto_connect());
1048}
1049
Paul Stewart3d9bcf52011-12-12 15:02:22 -08001050TEST_F(ManagerTest, SaveSuccessfulService) {
1051 scoped_refptr<MockProfile> profile(
1052 new StrictMock<MockProfile>(control_interface(), manager(), ""));
1053 AdoptProfile(manager(), profile);
1054 scoped_refptr<MockService> service(
1055 new NiceMock<MockService>(control_interface(),
1056 dispatcher(),
1057 manager()));
1058
1059 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
1060 ServiceRefPtr expect_service(service.get());
1061
1062 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
1063 .WillOnce(Return(false));
1064 manager()->RegisterService(service);
1065
1066 EXPECT_CALL(*service.get(), state())
1067 .WillRepeatedly(Return(Service::kStateConnected));
1068 EXPECT_CALL(*service.get(), IsConnected())
1069 .WillRepeatedly(Return(true));
1070 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
1071 .WillOnce(Return(true));
1072 manager()->UpdateService(service);
1073}
1074
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001075TEST_F(ManagerTest, AutoConnectOnRegister) {
1076 MockServiceRefPtr service = MakeAutoConnectableService();
1077 EXPECT_CALL(*service.get(), AutoConnect());
1078 manager()->RegisterService(service);
1079 dispatcher()->DispatchPendingEvents();
1080}
1081
1082TEST_F(ManagerTest, AutoConnectOnUpdate) {
1083 MockServiceRefPtr service1 = MakeAutoConnectableService();
1084 service1->set_priority(1);
1085 MockServiceRefPtr service2 = MakeAutoConnectableService();
1086 service2->set_priority(2);
1087 manager()->RegisterService(service1);
1088 manager()->RegisterService(service2);
1089 dispatcher()->DispatchPendingEvents();
1090
1091 EXPECT_CALL(*service1.get(), AutoConnect());
1092 EXPECT_CALL(*service2.get(), state())
1093 .WillRepeatedly(Return(Service::kStateFailure));
1094 EXPECT_CALL(*service2.get(), IsFailed())
1095 .WillRepeatedly(Return(true));
1096 EXPECT_CALL(*service2.get(), IsConnected())
1097 .WillRepeatedly(Return(false));
1098 manager()->UpdateService(service2);
1099 dispatcher()->DispatchPendingEvents();
1100}
1101
1102TEST_F(ManagerTest, AutoConnectOnDeregister) {
1103 MockServiceRefPtr service1 = MakeAutoConnectableService();
1104 service1->set_priority(1);
1105 MockServiceRefPtr service2 = MakeAutoConnectableService();
1106 service2->set_priority(2);
1107 manager()->RegisterService(service1);
1108 manager()->RegisterService(service2);
1109 dispatcher()->DispatchPendingEvents();
1110
1111 EXPECT_CALL(*service1.get(), AutoConnect());
1112 manager()->DeregisterService(service2);
1113 dispatcher()->DispatchPendingEvents();
1114}
1115
Chris Masone9be4a9d2011-05-16 15:44:09 -07001116} // namespace shill