blob: 8c75c8e6f7a2bbd49ace87b40fad76c0efb61742 [file] [log] [blame]
Chris Masone9be4a9d2011-05-16 15:44:09 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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 }
Paul Stewartf1ce5d22011-05-19 13:10:20 -0700166 protected:
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700167 scoped_refptr<MockWiFi> mock_wifi_;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700168 vector<scoped_refptr<MockDevice> > mock_devices_;
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800169 scoped_ptr<MockDeviceInfo> device_info_;
170
171 // This pointer is owned by the manager, and only tracked here for EXPECT*()
172 ManagerMockAdaptor *manager_adaptor_;
Chris Masone9be4a9d2011-05-16 15:44:09 -0700173};
174
Paul Stewart22aa71b2011-09-16 12:15:11 -0700175bool ManagerTest::ServiceOrderIs(ServiceRefPtr svc0, ServiceRefPtr svc1) {
176 return (svc0.get() == manager()->services_[0].get() &&
177 svc1.get() == manager()->services_[1].get());
178}
179
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700180TEST_F(ManagerTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700181 EXPECT_TRUE(manager()->store().Contains(flimflam::kStateProperty));
182 EXPECT_FALSE(manager()->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700183}
184
Chris Masone9be4a9d2011-05-16 15:44:09 -0700185TEST_F(ManagerTest, DeviceRegistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700186 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700187 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700188 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700189 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700190 ON_CALL(*mock_devices_[2].get(), TechnologyIs(Technology::kCellular))
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700191 .WillByDefault(Return(true));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700192
Paul Stewart22aa71b2011-09-16 12:15:11 -0700193 manager()->RegisterDevice(mock_devices_[0]);
194 manager()->RegisterDevice(mock_devices_[1]);
195 manager()->RegisterDevice(mock_devices_[2]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700196
Paul Stewart22aa71b2011-09-16 12:15:11 -0700197 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
198 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
199 EXPECT_TRUE(IsDeviceRegistered(mock_devices_[2], Technology::kCellular));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700200}
201
Paul Stewarta41e38d2011-11-11 07:47:29 -0800202TEST_F(ManagerTest, DeviceRegistrationAndStart) {
203 manager()->running_ = true;
204 mock_devices_[0]->powered_ = true;
205 mock_devices_[1]->powered_ = false;
206 EXPECT_CALL(*mock_devices_[0].get(), Start())
207 .Times(1);
208 EXPECT_CALL(*mock_devices_[1].get(), Start())
209 .Times(0);
210 manager()->RegisterDevice(mock_devices_[0]);
211 manager()->RegisterDevice(mock_devices_[1]);
212}
213
214TEST_F(ManagerTest, DeviceRegistrationWithProfile) {
215 MockProfile *profile = new MockProfile(control_interface(), manager(), "");
216 DeviceRefPtr device_ref(mock_devices_[0].get());
217 AdoptProfile(manager(), profile); // Passes ownership.
218 EXPECT_CALL(*profile, ConfigureDevice(device_ref));
219 EXPECT_CALL(*profile, Save());
220 manager()->RegisterDevice(mock_devices_[0]);
221}
222
Chris Masone9be4a9d2011-05-16 15:44:09 -0700223TEST_F(ManagerTest, DeviceDeregistration) {
Paul Stewart22aa71b2011-09-16 12:15:11 -0700224 ON_CALL(*mock_devices_[0].get(), TechnologyIs(Technology::kEthernet))
Chris Masone3c3f6a12011-07-01 10:01:41 -0700225 .WillByDefault(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700226 ON_CALL(*mock_devices_[1].get(), TechnologyIs(Technology::kWifi))
Chris Masone9be4a9d2011-05-16 15:44:09 -0700227 .WillByDefault(Return(true));
228
Gaurav Shah435de2c2011-11-17 19:01:07 -0800229 manager()->RegisterDevice(mock_devices_[0]);
230 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700231
Paul Stewart22aa71b2011-09-16 12:15:11 -0700232 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
233 ASSERT_TRUE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700234
Paul Stewart22aa71b2011-09-16 12:15:11 -0700235 EXPECT_CALL(*mock_devices_[0].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800236 manager()->DeregisterDevice(mock_devices_[0]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700237 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[0], Technology::kEthernet));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700238
Paul Stewart22aa71b2011-09-16 12:15:11 -0700239 EXPECT_CALL(*mock_devices_[1].get(), Stop());
Gaurav Shah435de2c2011-11-17 19:01:07 -0800240 manager()->DeregisterDevice(mock_devices_[1]);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700241 EXPECT_FALSE(IsDeviceRegistered(mock_devices_[1], Technology::kWifi));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700242}
243
244TEST_F(ManagerTest, ServiceRegistration) {
Chris Masone9d779932011-08-25 16:33:41 -0700245 // It's much easier and safer to use a real GLib for this test.
246 GLib glib;
Chris Masone2176a882011-09-14 22:29:15 -0700247 Manager manager(control_interface(),
248 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700249 &glib,
250 run_path(),
251 storage_path(),
252 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700253 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
254 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700255 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700256
Chris Masone9be4a9d2011-05-16 15:44:09 -0700257 scoped_refptr<MockService> mock_service(
Chris Masone2176a882011-09-14 22:29:15 -0700258 new NiceMock<MockService>(control_interface(),
259 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700260 &manager));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700261 scoped_refptr<MockService> mock_service2(
Chris Masone2176a882011-09-14 22:29:15 -0700262 new NiceMock<MockService>(control_interface(),
263 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700264 &manager));
mukesh agrawal51a7e932011-07-27 16:18:26 -0700265 string service1_name(mock_service->UniqueName());
266 string service2_name(mock_service2->UniqueName());
267
268 EXPECT_CALL(*mock_service.get(), GetRpcIdentifier())
269 .WillRepeatedly(Return(service1_name));
Chris Masone6791a432011-07-12 13:23:19 -0700270 EXPECT_CALL(*mock_service2.get(), GetRpcIdentifier())
mukesh agrawal51a7e932011-07-27 16:18:26 -0700271 .WillRepeatedly(Return(service2_name));
mukesh agrawal32399322011-09-01 10:53:43 -0700272 // TODO(quiche): make this EXPECT_CALL work (crosbug.com/20154)
Chris Masone9d779932011-08-25 16:33:41 -0700273 // EXPECT_CALL(*dynamic_cast<ManagerMockAdaptor *>(manager.adaptor_.get()),
mukesh agrawal32399322011-09-01 10:53:43 -0700274 // EmitRpcIdentifierArrayChanged(flimflam::kServicesProperty, _));
Chris Masone9be4a9d2011-05-16 15:44:09 -0700275
Chris Masone9d779932011-08-25 16:33:41 -0700276 manager.RegisterService(mock_service);
277 manager.RegisterService(mock_service2);
Chris Masone9be4a9d2011-05-16 15:44:09 -0700278
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800279 Error error;
280 vector<string> rpc_ids = manager.EnumerateAvailableServices(&error);
Chris Masone6791a432011-07-12 13:23:19 -0700281 set<string> ids(rpc_ids.begin(), rpc_ids.end());
mukesh agrawal51a7e932011-07-27 16:18:26 -0700282 EXPECT_EQ(2, ids.size());
283 EXPECT_TRUE(ContainsKey(ids, mock_service->GetRpcIdentifier()));
284 EXPECT_TRUE(ContainsKey(ids, mock_service2->GetRpcIdentifier()));
Chris Masone6791a432011-07-12 13:23:19 -0700285
Chris Masone9d779932011-08-25 16:33:41 -0700286 EXPECT_TRUE(manager.FindService(service1_name).get() != NULL);
287 EXPECT_TRUE(manager.FindService(service2_name).get() != NULL);
288
289 manager.Stop();
Chris Masone9be4a9d2011-05-16 15:44:09 -0700290}
291
Chris Masone6515aab2011-10-12 16:19:09 -0700292TEST_F(ManagerTest, RegisterKnownService) {
293 // It's much easier and safer to use a real GLib for this test.
294 GLib glib;
295 Manager manager(control_interface(),
296 dispatcher(),
297 &glib,
298 run_path(),
299 storage_path(),
300 string());
301 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
302 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700303 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700304 {
305 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
306 dispatcher(),
307 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700308 ASSERT_TRUE(profile->AdoptService(service1));
309 ASSERT_TRUE(profile->ContainsService(service1));
310 } // Force destruction of service1.
311
312 ServiceRefPtr service2(new ServiceUnderTest(control_interface(),
313 dispatcher(),
314 &manager));
315 manager.RegisterService(service2);
316 EXPECT_EQ(service2->profile().get(), profile.get());
317 manager.Stop();
318}
319
320TEST_F(ManagerTest, RegisterUnknownService) {
321 // It's much easier and safer to use a real GLib for this test.
322 GLib glib;
323 Manager manager(control_interface(),
324 dispatcher(),
325 &glib,
326 run_path(),
327 storage_path(),
328 string());
329 ProfileRefPtr profile(CreateProfileForManager(&manager, &glib));
330 ASSERT_TRUE(profile.get());
Paul Stewarta849a3d2011-11-03 05:54:09 -0700331 AdoptProfile(&manager, profile);
Chris Masone6515aab2011-10-12 16:19:09 -0700332 {
333 ServiceRefPtr service1(new ServiceUnderTest(control_interface(),
334 dispatcher(),
335 &manager));
Chris Masone6515aab2011-10-12 16:19:09 -0700336 ASSERT_TRUE(profile->AdoptService(service1));
337 ASSERT_TRUE(profile->ContainsService(service1));
338 } // Force destruction of service1.
339 scoped_refptr<MockService> mock_service2(
340 new NiceMock<MockService>(control_interface(),
341 dispatcher(),
342 &manager));
343 EXPECT_CALL(*mock_service2.get(), GetStorageIdentifier())
344 .WillRepeatedly(Return(mock_service2->UniqueName()));
345 manager.RegisterService(mock_service2);
346 EXPECT_NE(mock_service2->profile().get(), profile.get());
347 manager.Stop();
348}
349
Chris Masonea8a2c252011-06-27 22:16:30 -0700350TEST_F(ManagerTest, GetProperties) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700351 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700352 AdoptProfile(manager(), profile);
Chris Masonea8a2c252011-06-27 22:16:30 -0700353 map<string, ::DBus::Variant> props;
354 Error error(Error::kInvalidProperty, "");
355 {
356 ::DBus::Error dbus_error;
357 string expected("portal_list");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700358 manager()->mutable_store()->SetStringProperty(
359 flimflam::kCheckPortalListProperty,
360 expected,
361 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700362 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700363 ASSERT_FALSE(props.find(flimflam::kCheckPortalListProperty) == props.end());
364 EXPECT_EQ(props[flimflam::kCheckPortalListProperty].reader().get_string(),
365 expected);
366 }
367 {
368 ::DBus::Error dbus_error;
369 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700370 manager()->mutable_store()->SetBoolProperty(flimflam::kOfflineModeProperty,
371 expected,
372 &error);
Chris Masone9d779932011-08-25 16:33:41 -0700373 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700374 ASSERT_FALSE(props.find(flimflam::kOfflineModeProperty) == props.end());
375 EXPECT_EQ(props[flimflam::kOfflineModeProperty].reader().get_bool(),
376 expected);
377 }
378}
379
Chris Masone3c3f6a12011-07-01 10:01:41 -0700380TEST_F(ManagerTest, GetDevicesProperty) {
Chris Masoneb9c00592011-10-06 13:10:39 -0700381 ProfileRefPtr profile(new MockProfile(control_interface(), manager(), ""));
Paul Stewarta849a3d2011-11-03 05:54:09 -0700382 AdoptProfile(manager(), profile);
Gaurav Shah435de2c2011-11-17 19:01:07 -0800383 manager()->RegisterDevice(mock_devices_[0]);
384 manager()->RegisterDevice(mock_devices_[1]);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700385 {
386 map<string, ::DBus::Variant> props;
387 ::DBus::Error dbus_error;
Chris Masone9d779932011-08-25 16:33:41 -0700388 DBusAdaptor::GetProperties(manager()->store(), &props, &dbus_error);
Chris Masone3c3f6a12011-07-01 10:01:41 -0700389 ASSERT_FALSE(props.find(flimflam::kDevicesProperty) == props.end());
390 Strings devices =
391 props[flimflam::kDevicesProperty].operator vector<string>();
392 EXPECT_EQ(2, devices.size());
393 }
Chris Masone3c3f6a12011-07-01 10:01:41 -0700394}
395
Chris Masone6791a432011-07-12 13:23:19 -0700396TEST_F(ManagerTest, MoveService) {
Chris Masone2176a882011-09-14 22:29:15 -0700397 Manager manager(control_interface(),
398 dispatcher(),
Chris Masone6515aab2011-10-12 16:19:09 -0700399 glib(),
Chris Masone9d779932011-08-25 16:33:41 -0700400 run_path(),
401 storage_path(),
402 string());
Chris Masone6515aab2011-10-12 16:19:09 -0700403 scoped_refptr<MockService> s2(new MockService(control_interface(),
404 dispatcher(),
405 &manager));
406 // Inject an actual profile, backed by a fake StoreInterface
Chris Masoneb9c00592011-10-06 13:10:39 -0700407 {
Chris Masone6515aab2011-10-12 16:19:09 -0700408 Profile::Identifier id("irrelevant");
Chris Masoneb9c00592011-10-06 13:10:39 -0700409 ProfileRefPtr profile(
410 new Profile(control_interface(), &manager, id, "", false));
411 MockStore *storage = new MockStore;
Chris Masone6515aab2011-10-12 16:19:09 -0700412 // Say we don't have |s2| the first time asked, then that we do.
413 EXPECT_CALL(*storage, ContainsGroup(s2->GetStorageIdentifier()))
414 .WillOnce(Return(false))
415 .WillRepeatedly(Return(true));
416 EXPECT_CALL(*storage, Flush())
417 .Times(AnyNumber())
418 .WillRepeatedly(Return(true));
Chris Masoneb9c00592011-10-06 13:10:39 -0700419 profile->set_storage(storage);
Paul Stewarta849a3d2011-11-03 05:54:09 -0700420 AdoptProfile(&manager, profile);
Chris Masoneb9c00592011-10-06 13:10:39 -0700421 }
Chris Masone6515aab2011-10-12 16:19:09 -0700422 // Create a profile that already has |s2| in it.
423 ProfileRefPtr profile(new EphemeralProfile(control_interface(), &manager));
424 profile->AdoptService(s2);
Chris Masone9d779932011-08-25 16:33:41 -0700425
Chris Masone6515aab2011-10-12 16:19:09 -0700426 // Now, move the Service |s2| to another profile.
427 EXPECT_CALL(*s2.get(), Save(_)).WillOnce(Return(true));
428 ASSERT_TRUE(manager.MoveServiceToProfile(s2, manager.ActiveProfile()));
Chris Masone6791a432011-07-12 13:23:19 -0700429
430 // Force destruction of the original Profile, to ensure that the Service
431 // is kept alive and populated with data.
432 profile = NULL;
Chris Masone6515aab2011-10-12 16:19:09 -0700433 ASSERT_TRUE(manager.ActiveProfile()->ContainsService(s2));
Chris Masone9d779932011-08-25 16:33:41 -0700434 manager.Stop();
Chris Masone6791a432011-07-12 13:23:19 -0700435}
436
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700437TEST_F(ManagerTest, CreateProfile) {
438 // It's much easier to use real Glib here since we want the storage
439 // side-effects.
440 GLib glib;
441 ScopedTempDir temp_dir;
442 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
443
444 Manager manager(control_interface(),
445 dispatcher(),
446 &glib,
447 run_path(),
448 storage_path(),
449 temp_dir.path().value());
450
451 // Invalid name should be rejected.
452 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, ""));
453
454 // Valid name is still rejected because we can't create a profile
455 // that doesn't have a user component. Such profile names are
456 // reserved for the single DefaultProfile the manager creates
457 // at startup.
458 EXPECT_EQ(Error::kInvalidArguments, TestCreateProfile(&manager, "valid"));
459
460 // We should succeed in creating a valid user profile.
461 const char kProfile[] = "~user/profile";
462 EXPECT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile));
463
464 // We should fail in creating it a second time (already exists).
465 EXPECT_EQ(Error::kAlreadyExists, TestCreateProfile(&manager, kProfile));
466}
467
468TEST_F(ManagerTest, PushPopProfile) {
469 // It's much easier to use real Glib in creating a Manager for this
470 // test here since we want the storage side-effects.
471 GLib glib;
472 ScopedTempDir temp_dir;
473 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
474 Manager manager(control_interface(),
475 dispatcher(),
476 &glib,
477 run_path(),
478 storage_path(),
479 temp_dir.path().value());
480
481 // Pushing an invalid profile should fail.
482 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, ""));
483
484 // Pushing a default profile name should fail.
485 EXPECT_EQ(Error::kInvalidArguments, TestPushProfile(&manager, "default"));
486
487 const char kProfile0[] = "~user/profile0";
488 const char kProfile1[] = "~user/profile1";
489
490 // Create a couple of profiles.
491 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile0));
492 ASSERT_EQ(Error::kSuccess, TestCreateProfile(&manager, kProfile1));
493
494 // Push these profiles on the stack.
495 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile0));
496 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile1));
497
498 // Pushing a profile a second time should fail.
499 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile0));
500 EXPECT_EQ(Error::kAlreadyExists, TestPushProfile(&manager, kProfile1));
501
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800502 Error error;
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700503 // Active profile should be the last one we pushed.
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800504 EXPECT_EQ(kProfile1, "~" + manager.GetActiveProfileName(&error));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700505
506 // Make sure a profile name that doesn't exist fails.
507 const char kProfile2Id[] = "profile2";
508 const string kProfile2 = base::StringPrintf("~user/%s", kProfile2Id);
509 EXPECT_EQ(Error::kNotFound, TestPushProfile(&manager, kProfile2));
510
511 // Create a new service, with a specific storage name.
512 scoped_refptr<MockService> service(
513 new NiceMock<MockService>(control_interface(),
514 dispatcher(),
515 &manager));
516 const char kServiceName[] = "service_storage_name";
517 EXPECT_CALL(*service.get(), GetStorageIdentifier())
518 .WillRepeatedly(Return(kServiceName));
519 EXPECT_CALL(*service.get(), Load(_))
520 .WillRepeatedly(Return(true));
521
522 // Add this service to the manager -- it should end up in the ephemeral
523 // profile.
524 manager.RegisterService(service);
525 ASSERT_EQ(manager.ephemeral_profile_, service->profile());
526
527 // Create storage for a profile that contains the service storage name.
528 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile2Id,
529 kServiceName));
530
531 // When we push the profile, the service should move away from the
532 // ephemeral profile to this new profile since it has an entry for
533 // this service.
534 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile2));
535 EXPECT_NE(manager.ephemeral_profile_, service->profile());
536 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
537
538 // Insert another profile that should supersede ownership of the service.
539 const char kProfile3Id[] = "profile3";
540 const string kProfile3 = base::StringPrintf("~user/%s", kProfile3Id);
541 ASSERT_TRUE(CreateBackingStoreForService(&temp_dir, kProfile3Id,
542 kServiceName));
543 EXPECT_EQ(Error::kSuccess, TestPushProfile(&manager, kProfile3));
544 EXPECT_EQ(kProfile3, "~" + service->profile()->GetFriendlyName());
545
546 // Popping an invalid profile name should fail.
547 EXPECT_EQ(Error::kInvalidArguments, TestPopProfile(&manager, "~"));
548
549 // Popping an profile that is not at the top of the stack should fail.
550 EXPECT_EQ(Error::kNotSupported, TestPopProfile(&manager, kProfile0));
551
552 // Popping the top profile should succeed.
553 EXPECT_EQ(Error::kSuccess, TestPopProfile(&manager, kProfile3));
554
555 // Moreover the service should have switched profiles to profile 2.
556 EXPECT_EQ(kProfile2, "~" + service->profile()->GetFriendlyName());
557
558 // Popping the top profile should succeed.
559 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
560
561 // The service should now revert to the ephemeral profile.
562 EXPECT_EQ(manager.ephemeral_profile_, service->profile());
563
564 // Pop the remaining two services off the stack.
565 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
566 EXPECT_EQ(Error::kSuccess, TestPopAnyProfile(&manager));
567
568 // Next pop should fail with "stack is empty".
569 EXPECT_EQ(Error::kNotFound, TestPopAnyProfile(&manager));
570}
571
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700572TEST_F(ManagerTest, Dispatch) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700573 {
574 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700575 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700576 flimflam::kOfflineModeProperty,
577 PropertyStoreTest::kBoolV,
578 &error));
579 }
580 {
581 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700582 EXPECT_TRUE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700583 flimflam::kCountryProperty,
584 PropertyStoreTest::kStringV,
585 &error));
586 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700587 // Attempt to write with value of wrong type should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700588 {
589 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700590 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700591 flimflam::kCountryProperty,
592 PropertyStoreTest::kBoolV,
593 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700594 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700595 }
596 {
597 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700598 EXPECT_FALSE(DBusAdaptor::DispatchOnType(manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700599 flimflam::kOfflineModeProperty,
600 PropertyStoreTest::kStringV,
601 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700602 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700603 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700604 // Attempt to write R/O property should return InvalidArgs.
Chris Masonea8a2c252011-06-27 22:16:30 -0700605 {
606 ::DBus::Error error;
607 EXPECT_FALSE(DBusAdaptor::DispatchOnType(
mukesh agrawalde29fa82011-09-16 16:16:36 -0700608 manager()->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700609 flimflam::kEnabledTechnologiesProperty,
610 PropertyStoreTest::kStringsV,
611 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700612 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700613 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700614}
615
mukesh agrawal32399322011-09-01 10:53:43 -0700616TEST_F(ManagerTest, RequestScan) {
617 {
618 Error error;
Paul Stewart22aa71b2011-09-16 12:15:11 -0700619 manager()->RegisterDevice(mock_devices_[0].get());
620 manager()->RegisterDevice(mock_devices_[1].get());
621 EXPECT_CALL(*mock_devices_[0], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700622 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700623 EXPECT_CALL(*mock_devices_[0], Scan(_));
624 EXPECT_CALL(*mock_devices_[1], TechnologyIs(Technology::kWifi))
mukesh agrawal32399322011-09-01 10:53:43 -0700625 .WillRepeatedly(Return(false));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700626 EXPECT_CALL(*mock_devices_[1], Scan(_)).Times(0);
Chris Masone9d779932011-08-25 16:33:41 -0700627 manager()->RequestScan(flimflam::kTypeWifi, &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700628 }
629
630 {
631 Error error;
Chris Masone9d779932011-08-25 16:33:41 -0700632 manager()->RequestScan("bogus_device_type", &error);
mukesh agrawal32399322011-09-01 10:53:43 -0700633 EXPECT_EQ(Error::kInvalidArguments, error.type());
634 }
635}
636
mukesh agrawal7a4e4002011-09-06 11:26:05 -0700637TEST_F(ManagerTest, GetWifiServiceNoDevice) {
638 KeyValueStore args;
639 Error e;
640 manager()->GetWifiService(args, &e);
641 EXPECT_EQ(Error::kInvalidArguments, e.type());
642 EXPECT_EQ("no wifi devices available", e.message());
643}
644
645TEST_F(ManagerTest, GetWifiService) {
646 KeyValueStore args;
647 Error e;
648 WiFiServiceRefPtr wifi_service;
649
650 manager()->RegisterDevice(mock_wifi_);
651 EXPECT_CALL(*mock_wifi_, GetService(_, _))
652 .WillRepeatedly(Return(wifi_service));
653 manager()->GetWifiService(args, &e);
654}
655
Paul Stewart22aa71b2011-09-16 12:15:11 -0700656TEST_F(ManagerTest, TechnologyOrder) {
657 Error error;
658 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
659 string(flimflam::kTypeWifi), &error);
660 ASSERT_TRUE(error.IsSuccess());
661 EXPECT_EQ(manager()->GetTechnologyOrder(),
662 string(flimflam::kTypeEthernet) + "," +
663 string(flimflam::kTypeWifi));
664
665 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "x," +
666 string(flimflam::kTypeWifi), &error);
667 ASSERT_FALSE(error.IsSuccess());
668 EXPECT_EQ(Error::kInvalidArguments, error.type());
669 EXPECT_EQ(string(flimflam::kTypeEthernet) + "," +
670 string(flimflam::kTypeWifi),
671 manager()->GetTechnologyOrder());
672}
673
674TEST_F(ManagerTest, SortServices) {
mukesh agrawal00917ce2011-11-22 23:56:55 +0000675 // TODO(quiche): Some of these tests would probably fit better in
676 // service_unittest, since the actual comparison of Services is
677 // implemented in Service. (crosbug.com/23370)
678
Paul Stewart22aa71b2011-09-16 12:15:11 -0700679 scoped_refptr<MockService> mock_service0(
680 new NiceMock<MockService>(control_interface(),
681 dispatcher(),
682 manager()));
683 scoped_refptr<MockService> mock_service1(
684 new NiceMock<MockService>(control_interface(),
685 dispatcher(),
686 manager()));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700687
688 manager()->RegisterService(mock_service0);
689 manager()->RegisterService(mock_service1);
690
691 // Services should already be sorted by UniqueName
692 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
693
694 // Asking explictly to sort services should not change anything
695 manager()->SortServices();
696 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
697
698 // Two otherwise equal services should be reordered by strength
699 mock_service1->set_strength(1);
700 manager()->UpdateService(mock_service1);
701 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
702
703 // Security
Paul Stewart1ca3e852011-11-04 07:50:49 -0700704 mock_service0->set_security_level(1);
Paul Stewart22aa71b2011-09-16 12:15:11 -0700705 manager()->UpdateService(mock_service0);
706 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
707
708 // Technology
709 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Technology::kWifi))
710 .WillRepeatedly(Return(true));
711 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Technology::kEthernet))
712 .WillRepeatedly(Return(true));
713 // NB: Redefine default (false) return values so we don't use the default rule
714 // which makes the logs noisier
715 EXPECT_CALL(*mock_service0.get(), TechnologyIs(Ne(Technology::kWifi)))
716 .WillRepeatedly(Return(false));
717 EXPECT_CALL(*mock_service1.get(), TechnologyIs(Ne(Technology::kEthernet)))
718 .WillRepeatedly(Return(false));
719
720 Error error;
721 manager()->SetTechnologyOrder(string(flimflam::kTypeEthernet) + "," +
722 string(flimflam::kTypeWifi), &error);
723 EXPECT_TRUE(error.IsSuccess());
724 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
725
726 manager()->SetTechnologyOrder(string(flimflam::kTypeWifi) + "," +
727 string(flimflam::kTypeEthernet), &error);
728 EXPECT_TRUE(error.IsSuccess());
729 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
730
Gaurav Shah435de2c2011-11-17 19:01:07 -0800731 // Priority.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700732 mock_service0->set_priority(1);
733 manager()->UpdateService(mock_service0);
734 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
735
736 // Favorite
mukesh agrawal00917ce2011-11-22 23:56:55 +0000737 mock_service1->MakeFavorite();
Paul Stewart22aa71b2011-09-16 12:15:11 -0700738 manager()->UpdateService(mock_service1);
739 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
740
Gaurav Shah435de2c2011-11-17 19:01:07 -0800741 // Connecting.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700742 EXPECT_CALL(*mock_service0.get(), state())
743 .WillRepeatedly(Return(Service::kStateAssociating));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800744 EXPECT_CALL(*mock_service0.get(), IsConnecting())
745 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700746 manager()->UpdateService(mock_service0);
747 EXPECT_TRUE(ServiceOrderIs(mock_service0, mock_service1));
748
Gaurav Shah435de2c2011-11-17 19:01:07 -0800749 // Connected.
Paul Stewart22aa71b2011-09-16 12:15:11 -0700750 EXPECT_CALL(*mock_service1.get(), state())
751 .WillRepeatedly(Return(Service::kStateConnected));
Gaurav Shah435de2c2011-11-17 19:01:07 -0800752 EXPECT_CALL(*mock_service1.get(), IsConnected())
753 .WillRepeatedly(Return(true));
Paul Stewart22aa71b2011-09-16 12:15:11 -0700754 manager()->UpdateService(mock_service1);
755 EXPECT_TRUE(ServiceOrderIs(mock_service1, mock_service0));
756
757 manager()->DeregisterService(mock_service0);
758 manager()->DeregisterService(mock_service1);
759}
760
Paul Stewartc1dec4d2011-12-08 15:25:28 -0800761TEST_F(ManagerTest, SortServicesWithConnection) {
762 scoped_refptr<MockService> mock_service0(
763 new NiceMock<MockService>(control_interface(),
764 dispatcher(),
765 manager()));
766 scoped_refptr<MockService> mock_service1(
767 new NiceMock<MockService>(control_interface(),
768 dispatcher(),
769 manager()));
770
771 scoped_refptr<MockConnection> mock_connection0(
772 new NiceMock<MockConnection>(device_info_.get()));
773 scoped_refptr<MockConnection> mock_connection1(
774 new NiceMock<MockConnection>(device_info_.get()));
775
776 manager()->RegisterService(mock_service0);
777 manager()->RegisterService(mock_service1);
778
779 mock_service0->connection_ = mock_connection0;
780 mock_service1->connection_ = mock_connection1;
781
782 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
783 manager()->SortServices();
784
785 mock_service1->set_priority(1);
786 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(false));
787 EXPECT_CALL(*mock_connection1.get(), SetIsDefault(true));
788 manager()->SortServices();
789
790 EXPECT_CALL(*mock_connection0.get(), SetIsDefault(true));
791 mock_service1->connection_ = NULL;
792 manager()->DeregisterService(mock_service1);
793
794 mock_service0->connection_ = NULL;
795 manager()->DeregisterService(mock_service0);
796}
797
Gaurav Shah435de2c2011-11-17 19:01:07 -0800798TEST_F(ManagerTest, AvailableTechnologies) {
799 mock_devices_.push_back(new NiceMock<MockDevice>(control_interface(),
800 dispatcher(),
801 manager(),
802 "null4",
803 "addr4",
804 0));
805 manager()->RegisterDevice(mock_devices_[0]);
806 manager()->RegisterDevice(mock_devices_[1]);
807 manager()->RegisterDevice(mock_devices_[2]);
808 manager()->RegisterDevice(mock_devices_[3]);
809
810 ON_CALL(*mock_devices_[0].get(), technology())
811 .WillByDefault(Return(Technology::kEthernet));
812 ON_CALL(*mock_devices_[1].get(), technology())
813 .WillByDefault(Return(Technology::kWifi));
814 ON_CALL(*mock_devices_[2].get(), technology())
815 .WillByDefault(Return(Technology::kCellular));
816 ON_CALL(*mock_devices_[3].get(), technology())
817 .WillByDefault(Return(Technology::kWifi));
818
819 set<string> expected_technologies;
820 expected_technologies.insert(Technology::NameFromIdentifier(
821 Technology::kEthernet));
822 expected_technologies.insert(Technology::NameFromIdentifier(
823 Technology::kWifi));
824 expected_technologies.insert(Technology::NameFromIdentifier(
825 Technology::kCellular));
826 Error error;
827 vector<string> technologies = manager()->AvailableTechnologies(&error);
828
829 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
830 ContainerEq(expected_technologies));
831}
832
833TEST_F(ManagerTest, ConnectedTechnologies) {
834 scoped_refptr<MockService> connected_service1(
835 new NiceMock<MockService>(control_interface(),
836 dispatcher(),
837 manager()));
838 scoped_refptr<MockService> connected_service2(
839 new NiceMock<MockService>(control_interface(),
840 dispatcher(),
841 manager()));
842 scoped_refptr<MockService> disconnected_service1(
843 new NiceMock<MockService>(control_interface(),
844 dispatcher(),
845 manager()));
846 scoped_refptr<MockService> disconnected_service2(
847 new NiceMock<MockService>(control_interface(),
848 dispatcher(),
849 manager()));
850
851 ON_CALL(*connected_service1.get(), IsConnected())
852 .WillByDefault(Return(true));
853 ON_CALL(*connected_service2.get(), IsConnected())
854 .WillByDefault(Return(true));
855
856 manager()->RegisterService(connected_service1);
857 manager()->RegisterService(connected_service2);
858 manager()->RegisterService(disconnected_service1);
859 manager()->RegisterService(disconnected_service2);
860
861 manager()->RegisterDevice(mock_devices_[0]);
862 manager()->RegisterDevice(mock_devices_[1]);
863 manager()->RegisterDevice(mock_devices_[2]);
864 manager()->RegisterDevice(mock_devices_[3]);
865
866 ON_CALL(*mock_devices_[0].get(), technology())
867 .WillByDefault(Return(Technology::kEthernet));
868 ON_CALL(*mock_devices_[1].get(), technology())
869 .WillByDefault(Return(Technology::kWifi));
870 ON_CALL(*mock_devices_[2].get(), technology())
871 .WillByDefault(Return(Technology::kCellular));
872 ON_CALL(*mock_devices_[3].get(), technology())
873 .WillByDefault(Return(Technology::kWifi));
874
875 mock_devices_[0]->SelectService(connected_service1);
876 mock_devices_[1]->SelectService(disconnected_service1);
877 mock_devices_[2]->SelectService(disconnected_service2);
878 mock_devices_[3]->SelectService(connected_service2);
879
880 set<string> expected_technologies;
881 expected_technologies.insert(Technology::NameFromIdentifier(
882 Technology::kEthernet));
883 expected_technologies.insert(Technology::NameFromIdentifier(
884 Technology::kWifi));
885 Error error;
886
887 vector<string> technologies = manager()->ConnectedTechnologies(&error);
888 EXPECT_THAT(set<string>(technologies.begin(), technologies.end()),
889 ContainerEq(expected_technologies));
890}
891
892TEST_F(ManagerTest, DefaultTechnology) {
893 scoped_refptr<MockService> connected_service(
894 new NiceMock<MockService>(control_interface(),
895 dispatcher(),
896 manager()));
897 scoped_refptr<MockService> disconnected_service(
898 new NiceMock<MockService>(control_interface(),
899 dispatcher(),
900 manager()));
901
902 // Connected. WiFi.
903 ON_CALL(*connected_service.get(), IsConnected())
904 .WillByDefault(Return(true));
905 ON_CALL(*connected_service.get(), state())
906 .WillByDefault(Return(Service::kStateConnected));
907 ON_CALL(*connected_service.get(), technology())
908 .WillByDefault(Return(Technology::kWifi));
909
910 // Disconnected. Ethernet.
911 ON_CALL(*disconnected_service.get(), technology())
912 .WillByDefault(Return(Technology::kEthernet));
913
914 manager()->RegisterService(disconnected_service);
915 Error error;
916 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(""));
917
918
919 manager()->RegisterService(connected_service);
920 // Connected service should be brought to the front now.
921 string expected_technology =
922 Technology::NameFromIdentifier(Technology::kWifi);
923 EXPECT_THAT(manager()->DefaultTechnology(&error), StrEq(expected_technology));
924}
925
Thieu Le1271d682011-11-02 22:48:19 +0000926TEST_F(ManagerTest, DisconnectServicesOnStop) {
927 scoped_refptr<MockService> mock_service(
928 new NiceMock<MockService>(control_interface(),
929 dispatcher(),
930 manager()));
931 manager()->RegisterService(mock_service);
mukesh agrawal0ed0f2e2011-12-05 20:36:17 +0000932 EXPECT_CALL(*mock_service.get(), Disconnect(_)).Times(1);
Thieu Le1271d682011-11-02 22:48:19 +0000933 manager()->Stop();
934}
935
mukesh agrawal00917ce2011-11-22 23:56:55 +0000936TEST_F(ManagerTest, UpdateServiceConnected) {
937 scoped_refptr<MockService> mock_service(
938 new NiceMock<MockService>(control_interface(),
939 dispatcher(),
940 manager()));
941 manager()->RegisterService(mock_service);
942 EXPECT_FALSE(mock_service->favorite());
943 EXPECT_FALSE(mock_service->auto_connect());
944
Gaurav Shah435de2c2011-11-17 19:01:07 -0800945 EXPECT_CALL(*mock_service.get(), IsConnected())
946 .WillRepeatedly(Return(true));
mukesh agrawal00917ce2011-11-22 23:56:55 +0000947 manager()->UpdateService(mock_service);
948 // We can't EXPECT_CALL(..., MakeFavorite), because that requires us
949 // to mock out MakeFavorite. And mocking that out would break the
950 // SortServices test. (crosbug.com/23370)
951 EXPECT_TRUE(mock_service->favorite());
952 EXPECT_TRUE(mock_service->auto_connect());
953}
954
Paul Stewart3d9bcf52011-12-12 15:02:22 -0800955TEST_F(ManagerTest, SaveSuccessfulService) {
956 scoped_refptr<MockProfile> profile(
957 new StrictMock<MockProfile>(control_interface(), manager(), ""));
958 AdoptProfile(manager(), profile);
959 scoped_refptr<MockService> service(
960 new NiceMock<MockService>(control_interface(),
961 dispatcher(),
962 manager()));
963
964 // Re-cast this back to a ServiceRefPtr, so EXPECT arguments work correctly.
965 ServiceRefPtr expect_service(service.get());
966
967 EXPECT_CALL(*profile.get(), ConfigureService(expect_service))
968 .WillOnce(Return(false));
969 manager()->RegisterService(service);
970
971 EXPECT_CALL(*service.get(), state())
972 .WillRepeatedly(Return(Service::kStateConnected));
973 EXPECT_CALL(*service.get(), IsConnected())
974 .WillRepeatedly(Return(true));
975 EXPECT_CALL(*profile.get(), AdoptService(expect_service))
976 .WillOnce(Return(true));
977 manager()->UpdateService(service);
978}
979
Chris Masone9be4a9d2011-05-16 15:44:09 -0700980} // namespace shill