1// 2// Copyright (C) 2013 The Android Open Source Project 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include "shill/service.h" 18 19#include <algorithm> 20#include <map> 21#include <memory> 22#include <string> 23#include <vector> 24 25#include <base/bind.h> 26#if defined(__ANDROID__) 27#include <dbus/service_constants.h> 28#else 29#include <chromeos/dbus/service_constants.h> 30#endif // __ANDROID__ 31#include <gtest/gtest.h> 32#include <gmock/gmock.h> 33 34#include "shill/ethernet/ethernet_service.h" 35#include "shill/event_dispatcher.h" 36#include "shill/manager.h" 37#include "shill/mock_adaptors.h" 38#include "shill/mock_connection.h" 39#include "shill/mock_control.h" 40#include "shill/mock_device_info.h" 41#include "shill/mock_dhcp_properties.h" 42#include "shill/mock_event_dispatcher.h" 43#include "shill/mock_log.h" 44#include "shill/mock_manager.h" 45#include "shill/mock_power_manager.h" 46#include "shill/mock_profile.h" 47#include "shill/mock_service.h" 48#include "shill/mock_store.h" 49#include "shill/net/mock_time.h" 50#include "shill/property_store_unittest.h" 51#include "shill/service_property_change_test.h" 52#include "shill/service_sorter.h" 53#include "shill/service_under_test.h" 54#include "shill/testing.h" 55 56#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 57#include "shill/mock_eap_credentials.h" 58#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 59 60using base::Bind; 61using base::Unretained; 62using std::deque; 63using std::map; 64using std::string; 65using std::vector; 66using testing::_; 67using testing::AnyNumber; 68using testing::AtLeast; 69using testing::DefaultValue; 70using testing::DoAll; 71using testing::HasSubstr; 72using testing::Mock; 73using testing::NiceMock; 74using testing::Return; 75using testing::ReturnNull; 76using testing::ReturnRef; 77using testing::StrictMock; 78using testing::SetArgumentPointee; 79using testing::Test; 80using testing::Values; 81 82namespace shill { 83 84class ServiceTest : public PropertyStoreTest { 85 public: 86 ServiceTest() 87 : mock_manager_(control_interface(), dispatcher(), metrics()), 88 service_(new ServiceUnderTest(control_interface(), 89 dispatcher(), 90 metrics(), 91 &mock_manager_)), 92 service2_(new ServiceUnderTest(control_interface(), 93 dispatcher(), 94 metrics(), 95 &mock_manager_)), 96 storage_id_(ServiceUnderTest::kStorageId), 97#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 98 eap_(new MockEapCredentials()), 99#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 100 power_manager_(new MockPowerManager(nullptr, &control_)) { 101 ON_CALL(control_, CreatePowerManagerProxy(_, _, _)) 102 .WillByDefault(ReturnNull()); 103 104 service_->time_ = &time_; 105 service_->disconnects_.time_ = &time_; 106 service_->misconnects_.time_ = &time_; 107 DefaultValue<Timestamp>::Set(Timestamp()); 108#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 109 service_->eap_.reset(eap_); // Passes ownership. 110#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 111 mock_manager_.running_ = true; 112 mock_manager_.set_power_manager(power_manager_); // Passes ownership. 113 } 114 115 virtual ~ServiceTest() {} 116 117 MOCK_METHOD1(TestCallback, void(const Error& error)); 118 119 protected: 120 typedef scoped_refptr<MockProfile> MockProfileRefPtr; 121 122 ServiceMockAdaptor* GetAdaptor() { 123 return static_cast<ServiceMockAdaptor*>(service_->adaptor()); 124 } 125 126 string GetFriendlyName() { return service_->friendly_name(); } 127 128 void SetManagerRunning(bool running) { mock_manager_.running_ = running; } 129 130 void SetSuspending(bool suspending) { 131 power_manager_->suspending_ = suspending; 132 } 133 134 bool GetExplicitlyDisconnected() const { 135 return service_->explicitly_disconnected_; 136 } 137 138 void SetExplicitlyDisconnected(bool explicitly) { 139 service_->explicitly_disconnected_ = explicitly; 140 } 141 142 void SetStateField(Service::ConnectState state) { service_->state_ = state; } 143 144 Service::ConnectState GetPreviousState() const { 145 return service_->previous_state_; 146 } 147 148 void NoteDisconnectEvent() { 149 service_->NoteDisconnectEvent(); 150 } 151 152 EventHistory* GetDisconnects() { 153 return &service_->disconnects_; 154 } 155 EventHistory* GetMisconnects() { 156 return &service_->misconnects_; 157 } 158 159 Timestamp GetTimestamp(int monotonic_seconds, int boottime_seconds, 160 const string& wall_clock) { 161 struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 }; 162 struct timeval boottime = { .tv_sec = boottime_seconds, .tv_usec = 0 }; 163 return Timestamp(monotonic, boottime, wall_clock); 164 } 165 166 void PushTimestamp(EventHistory* events, 167 int monotonic_seconds, 168 int boottime_seconds, 169 const string& wall_clock) { 170 events->RecordEventInternal( 171 GetTimestamp(monotonic_seconds, boottime_seconds, wall_clock)); 172 } 173 174 int GetDisconnectsMonitorSeconds() { 175 return Service::kDisconnectsMonitorSeconds; 176 } 177 178 int GetMisconnectsMonitorSeconds() { 179 return Service::kMisconnectsMonitorSeconds; 180 } 181 182 int GetMaxDisconnectEventHistory() { 183 return Service::kMaxDisconnectEventHistory; 184 } 185 186 int GetMaxMisconnectEventHistory() { 187 return Service::kMaxMisconnectEventHistory; 188 } 189 190 bool GetAutoConnect(Error* error) { 191 return service_->GetAutoConnect(error); 192 } 193 194 void ClearAutoConnect(Error* error) { 195 service_->ClearAutoConnect(error); 196 } 197 198 bool SetAutoConnectFull(bool connect, Error* error) { 199 return service_->SetAutoConnectFull(connect, error); 200 } 201 202 bool SortingOrderIs(const ServiceRefPtr& service0, 203 const ServiceRefPtr& service1, 204 bool should_compare_connectivity_state) { 205 vector<ServiceRefPtr> services; 206 services.push_back(service1); 207 services.push_back(service0); 208 std::sort(services.begin(), services.end(), 209 ServiceSorter(&mock_manager_, should_compare_connectivity_state, 210 technology_order_for_sorting_)); 211 return (service0.get() == services[0].get() && 212 service1.get() == services[1].get()); 213 } 214 215 bool DefaultSortingOrderIs(const ServiceRefPtr& service0, 216 const ServiceRefPtr& service1) { 217 const bool kShouldCompareConnectivityState = true; 218 return SortingOrderIs( 219 service0, service1, kShouldCompareConnectivityState); 220 } 221 222 MockManager mock_manager_; 223 MockTime time_; 224 scoped_refptr<ServiceUnderTest> service_; 225 scoped_refptr<ServiceUnderTest> service2_; 226 string storage_id_; 227 NiceMock<MockControl> control_; 228#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 229 MockEapCredentials* eap_; // Owned by |service_|. 230#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 231 MockPowerManager* power_manager_; // Owned by |mock_manager_|. 232 vector<Technology::Identifier> technology_order_for_sorting_; 233}; 234 235class AllMockServiceTest : public testing::Test { 236 public: 237 AllMockServiceTest() 238 : metrics_(&dispatcher_), 239 manager_(&control_interface_, &dispatcher_, &metrics_), 240 service_(new ServiceUnderTest(&control_interface_, 241 &dispatcher_, 242 &metrics_, 243 &manager_)) { } 244 virtual ~AllMockServiceTest() {} 245 246 protected: 247 MockControl control_interface_; 248 StrictMock<MockEventDispatcher> dispatcher_; 249 NiceMock<MockMetrics> metrics_; 250 MockManager manager_; 251 scoped_refptr<ServiceUnderTest> service_; 252}; 253 254TEST_F(ServiceTest, Constructor) { 255 EXPECT_TRUE(service_->save_credentials_); 256 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_); 257 EXPECT_EQ(Service::kStateIdle, service_->state()); 258 EXPECT_FALSE(service_->has_ever_connected()); 259 EXPECT_EQ(0, service_->previous_error_serial_number_); 260 EXPECT_EQ("", service_->previous_error_); 261} 262 263TEST_F(ServiceTest, CalculateState) { 264 service_->state_ = Service::kStateConnected; 265 Error error; 266 EXPECT_EQ(kStateReady, service_->CalculateState(&error)); 267 EXPECT_TRUE(error.IsSuccess()); 268} 269 270TEST_F(ServiceTest, CalculateTechnology) { 271 service_->technology_ = Technology::kWifi; 272 Error error; 273 EXPECT_EQ(kTypeWifi, service_->CalculateTechnology(&error)); 274 EXPECT_TRUE(error.IsSuccess()); 275} 276 277TEST_F(ServiceTest, GetProperties) { 278 { 279 brillo::VariantDictionary props; 280 Error error; 281 string expected("true"); 282 service_->mutable_store()->SetStringProperty(kCheckPortalProperty, 283 expected, 284 &error); 285 EXPECT_TRUE(service_->store().GetProperties(&props, &error)); 286 ASSERT_FALSE(props.find(kCheckPortalProperty) == props.end()); 287 EXPECT_TRUE(props[kCheckPortalProperty].IsTypeCompatible<string>()); 288 EXPECT_EQ(props[kCheckPortalProperty].Get<string>(), expected); 289 } 290 { 291 brillo::VariantDictionary props; 292 Error error; 293 bool expected = true; 294 service_->mutable_store()->SetBoolProperty(kAutoConnectProperty, 295 expected, 296 &error); 297 EXPECT_TRUE(service_->store().GetProperties(&props, &error)); 298 ASSERT_FALSE(props.find(kAutoConnectProperty) == props.end()); 299 EXPECT_TRUE(props[kAutoConnectProperty].IsTypeCompatible<bool>()); 300 EXPECT_EQ(props[kAutoConnectProperty].Get<bool>(), expected); 301 } 302 { 303 brillo::VariantDictionary props; 304 Error error; 305 EXPECT_TRUE(service_->store().GetProperties(&props, &error)); 306 ASSERT_FALSE(props.find(kConnectableProperty) == props.end()); 307 EXPECT_TRUE(props[kConnectableProperty].IsTypeCompatible<bool>()); 308 EXPECT_EQ(props[kConnectableProperty].Get<bool>(), false); 309 } 310 { 311 brillo::VariantDictionary props; 312 Error error; 313 int32_t expected = 127; 314 service_->mutable_store()->SetInt32Property(kPriorityProperty, 315 expected, 316 &error); 317 EXPECT_TRUE(service_->store().GetProperties(&props, &error)); 318 ASSERT_FALSE(props.find(kPriorityProperty) == props.end()); 319 EXPECT_TRUE(props[kPriorityProperty].IsTypeCompatible<int32_t>()); 320 EXPECT_EQ(props[kPriorityProperty].Get<int32_t>(), expected); 321 } 322 { 323 brillo::VariantDictionary props; 324 Error error; 325 service_->store().GetProperties(&props, &error); 326 ASSERT_FALSE(props.find(kDeviceProperty) == props.end()); 327 EXPECT_TRUE(props[kDeviceProperty].IsTypeCompatible<dbus::ObjectPath>()); 328 EXPECT_EQ(props[kDeviceProperty].Get<dbus::ObjectPath>().value(), 329 string(ServiceUnderTest::kRpcId)); 330 } 331} 332 333TEST_F(ServiceTest, SetProperty) { 334 { 335 Error error; 336 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty( 337 kSaveCredentialsProperty, PropertyStoreTest::kBoolV, &error)); 338 } 339 { 340 Error error; 341 const int32_t priority = 1; 342 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty( 343 kPriorityProperty, brillo::Any(priority), &error)); 344 } 345 { 346 Error error; 347 const string guid("not default"); 348 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty( 349 kGuidProperty, brillo::Any(guid), &error)); 350 } 351#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 352 // Ensure that EAP properties cannot be set on services with no EAP 353 // credentials. Use service2_ here since we're have some code in 354 // ServiceTest::SetUp() that fiddles with service_->eap_. 355 { 356 Error error; 357 string eap("eap eep eip!"); 358 EXPECT_FALSE(service2_->mutable_store()->SetAnyProperty( 359 kEapMethodProperty, brillo::Any(eap), &error)); 360 ASSERT_TRUE(error.IsFailure()); 361 EXPECT_EQ(Error::kInvalidProperty, error.type()); 362 // Now plumb in eap credentials, and try again. 363 service2_->SetEapCredentials(new EapCredentials()); 364 EXPECT_TRUE(service2_->mutable_store()->SetAnyProperty( 365 kEapMethodProperty, brillo::Any(eap), &error)); 366 } 367#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 368 // Ensure that an attempt to write a R/O property returns InvalidArgs error. 369 { 370 Error error; 371 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty( 372 kConnectableProperty, PropertyStoreTest::kBoolV, &error)); 373 ASSERT_TRUE(error.IsFailure()); 374 EXPECT_EQ(Error::kInvalidArguments, error.type()); 375 } 376 { 377 bool auto_connect = true; 378 Error error; 379 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty( 380 kAutoConnectProperty, brillo::Any(auto_connect), &error)); 381 } 382 // Ensure that we can perform a trivial set of the Name property (to its 383 // current value) but an attempt to set the property to a different value 384 // fails. 385 { 386 Error error; 387 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty( 388 kNameProperty, brillo::Any(GetFriendlyName()), &error)); 389 EXPECT_FALSE(error.IsFailure()); 390 } 391 { 392 Error error; 393 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty( 394 kNameProperty, PropertyStoreTest::kStringV, &error)); 395 ASSERT_TRUE(error.IsFailure()); 396 EXPECT_EQ(Error::kInvalidArguments, error.type()); 397 } 398} 399 400TEST_F(ServiceTest, GetLoadableStorageIdentifier) { 401 NiceMock<MockStore> storage; 402 EXPECT_CALL(storage, ContainsGroup(storage_id_)) 403 .WillOnce(Return(false)) 404 .WillOnce(Return(true)); 405 EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage)); 406 EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage)); 407} 408 409TEST_F(ServiceTest, IsLoadableFrom) { 410 NiceMock<MockStore> storage; 411 EXPECT_CALL(storage, ContainsGroup(storage_id_)) 412 .WillOnce(Return(false)) 413 .WillOnce(Return(true)); 414 EXPECT_FALSE(service_->IsLoadableFrom(storage)); 415 EXPECT_TRUE(service_->IsLoadableFrom(storage)); 416} 417 418#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 419class ServiceWithOnEapCredentialsChangedOverride : public ServiceUnderTest { 420 public: 421 ServiceWithOnEapCredentialsChangedOverride( 422 ControlInterface* control_interface, 423 EventDispatcher* dispatcher, 424 Metrics* metrics, 425 Manager* manager, 426 EapCredentials* eap) 427 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) { 428 SetEapCredentials(eap); 429 } 430 void OnEapCredentialsChanged(Service::UpdateCredentialsReason) override { 431 SetHasEverConnected(false); 432 } 433}; 434#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 435 436TEST_F(ServiceTest, Load) { 437#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 438 MockEapCredentials* eap = new MockEapCredentials(); // Owned by |service|. 439 scoped_refptr<ServiceWithOnEapCredentialsChangedOverride> service( 440 new ServiceWithOnEapCredentialsChangedOverride(control_interface(), 441 dispatcher(), 442 metrics(), 443 &mock_manager_, 444 eap)); 445#else 446 scoped_refptr<ServiceUnderTest> service( 447 new ServiceUnderTest(control_interface(), 448 dispatcher(), 449 metrics(), 450 &mock_manager_)); 451#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 452 453 NiceMock<MockStore> storage; 454 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true)); 455 const string kCheckPortal("check-portal"); 456 const string kGUID("guid"); 457 const bool kHasEverConnected = true; 458 const int kPriority = 20; 459 const string kProxyConfig("proxy-config"); 460 const string kUIData("ui-data"); 461 EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber()); 462 EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber()); 463 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _)) 464 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true))); 465 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _)) 466 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true))); 467 EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _)) 468 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true))); 469 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _)) 470 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true))); 471 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _)) 472 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true))); 473 EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber()); 474 EXPECT_CALL(storage, 475 GetBool(storage_id_, Service::kStorageSaveCredentials, _)); 476 EXPECT_CALL(storage, 477 GetBool(storage_id_, Service::kStorageHasEverConnected, _)) 478 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected), 479 Return(true))); 480#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 481 EXPECT_CALL(*eap, Load(&storage, storage_id_)); 482#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 483 MockDhcpProperties* dhcp_props = new MockDhcpProperties(); 484 service->dhcp_properties_.reset(dhcp_props); 485 EXPECT_CALL(*dhcp_props, Load(&storage, storage_id_)); 486 487 EXPECT_TRUE(service->Load(&storage)); 488 EXPECT_EQ(kCheckPortal, service->check_portal_); 489 EXPECT_EQ(kGUID, service->guid_); 490 EXPECT_TRUE(service->has_ever_connected_); 491 EXPECT_EQ(kProxyConfig, service->proxy_config_); 492 EXPECT_EQ(kUIData, service->ui_data_); 493 494 Mock::VerifyAndClearExpectations(&storage); 495#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 496 Mock::VerifyAndClearExpectations(eap_); 497#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 498 Mock::VerifyAndClearExpectations(dhcp_props); 499 500 // Assure that parameters are set to default if not available in the profile. 501 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true)); 502 EXPECT_CALL(storage, GetBool(storage_id_, _, _)) 503 .WillRepeatedly(Return(false)); 504 EXPECT_CALL(storage, GetString(storage_id_, _, _)) 505 .WillRepeatedly(Return(false)); 506 EXPECT_CALL(storage, GetInt(storage_id_, _, _)) 507 .WillRepeatedly(Return(false)); 508#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 509 EXPECT_CALL(*eap, Load(&storage, storage_id_)); 510#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 511 EXPECT_CALL(*dhcp_props, Load(&storage, storage_id_)); 512 513 EXPECT_TRUE(service->Load(&storage)); 514 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_); 515 EXPECT_EQ("", service->guid_); 516 EXPECT_EQ("", service->proxy_config_); 517 EXPECT_EQ("", service->ui_data_); 518 519 // has_ever_connected_ flag will reset when EAP credential changes. 520#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 521 EXPECT_FALSE(service->has_ever_connected_); 522#else 523 EXPECT_TRUE(service->has_ever_connected_); 524#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 525} 526 527TEST_F(ServiceTest, LoadFail) { 528 StrictMock<MockStore> storage; 529 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false)); 530 EXPECT_FALSE(service_->Load(&storage)); 531} 532 533TEST_F(ServiceTest, LoadAutoConnect) { 534 NiceMock<MockStore> storage; 535 EXPECT_CALL(storage, ContainsGroup(storage_id_)) 536 .WillRepeatedly(Return(true)); 537 EXPECT_CALL(storage, GetBool(storage_id_, _, _)) 538 .WillRepeatedly(Return(false)); 539 EXPECT_CALL(storage, GetString(storage_id_, _, _)) 540 .WillRepeatedly(Return(false)); 541 EXPECT_CALL(storage, GetInt(storage_id_, _, _)) 542 .WillRepeatedly(Return(false)); 543#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 544 EXPECT_CALL(*eap_, Load(&storage, storage_id_)).Times(AnyNumber()); 545#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 546 547 std::unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties()); 548 EXPECT_CALL(*dhcp_props.get(), Load(&storage, storage_id_)).Times(AnyNumber()); 549 service_->dhcp_properties_ = std::move(dhcp_props); 550 551 // Three of each expectation so we can test Favorite == unset, false, true. 552 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageAutoConnect, _)) 553 .WillOnce(Return(false)) 554 .WillOnce(Return(false)) 555 .WillOnce(Return(false)) 556 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 557 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 558 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 559 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))) 560 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))) 561 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))); 562 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageFavorite, _)) 563 .WillOnce(Return(false)) 564 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 565 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))) 566 .WillOnce(Return(false)) 567 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 568 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))) 569 .WillOnce(Return(false)) 570 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true))) 571 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true))); 572 573 // AutoConnect is unset, Favorite is unset. 574 EXPECT_TRUE(service_->Load(&storage)); 575 EXPECT_FALSE(service_->auto_connect()); 576 EXPECT_FALSE(service_->retain_auto_connect()); 577 578 // AutoConnect is unset, Favorite is false. 579 EXPECT_TRUE(service_->Load(&storage)); 580 EXPECT_FALSE(service_->auto_connect()); 581 EXPECT_FALSE(service_->retain_auto_connect()); 582 583 // AutoConnect is unset, Favorite is true. 584 EXPECT_TRUE(service_->Load(&storage)); 585 EXPECT_FALSE(service_->auto_connect()); 586 EXPECT_TRUE(service_->retain_auto_connect()); 587 588 // AutoConnect is false, Favorite is unset. 589 EXPECT_TRUE(service_->Load(&storage)); 590 EXPECT_FALSE(service_->auto_connect()); 591 EXPECT_TRUE(service_->retain_auto_connect()); 592 593 // AutoConnect is false, Favorite is false. 594 EXPECT_TRUE(service_->Load(&storage)); 595 EXPECT_FALSE(service_->auto_connect()); 596 EXPECT_FALSE(service_->retain_auto_connect()); 597 598 // AutoConnect is false, Favorite is true. 599 EXPECT_TRUE(service_->Load(&storage)); 600 EXPECT_FALSE(service_->auto_connect()); 601 EXPECT_TRUE(service_->retain_auto_connect()); 602 603 // AutoConnect is true, Favorite is unset. 604 EXPECT_TRUE(service_->Load(&storage)); 605 EXPECT_TRUE(service_->auto_connect()); 606 EXPECT_TRUE(service_->retain_auto_connect()); 607 608 // AutoConnect is true, Favorite is false (invalid case). 609 EXPECT_TRUE(service_->Load(&storage)); 610 EXPECT_TRUE(service_->auto_connect()); 611 EXPECT_FALSE(service_->retain_auto_connect()); 612 613 // AutoConnect is true, Favorite is true. 614 EXPECT_TRUE(service_->Load(&storage)); 615 EXPECT_TRUE(service_->auto_connect()); 616 EXPECT_TRUE(service_->retain_auto_connect()); 617} 618 619TEST_F(ServiceTest, SaveString) { 620 MockStore storage; 621 static const char kKey[] = "test-key"; 622 static const char kData[] = "test-data"; 623 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData)) 624 .WillOnce(Return(true)); 625 service_->SaveString(&storage, storage_id_, kKey, kData, false, true); 626} 627 628TEST_F(ServiceTest, SaveStringCrypted) { 629 MockStore storage; 630 static const char kKey[] = "test-key"; 631 static const char kData[] = "test-data"; 632 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData)) 633 .WillOnce(Return(true)); 634 service_->SaveString(&storage, storage_id_, kKey, kData, true, true); 635} 636 637TEST_F(ServiceTest, SaveStringDontSave) { 638 MockStore storage; 639 static const char kKey[] = "test-key"; 640 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey)) 641 .WillOnce(Return(true)); 642 service_->SaveString(&storage, storage_id_, kKey, "data", false, false); 643} 644 645TEST_F(ServiceTest, SaveStringEmpty) { 646 MockStore storage; 647 static const char kKey[] = "test-key"; 648 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey)) 649 .WillOnce(Return(true)); 650 service_->SaveString(&storage, storage_id_, kKey, "", true, true); 651} 652 653TEST_F(ServiceTest, Save) { 654 NiceMock<MockStore> storage; 655 EXPECT_CALL(storage, SetString(storage_id_, _, _)) 656 .Times(AtLeast(1)) 657 .WillRepeatedly(Return(true)); 658 EXPECT_CALL(storage, DeleteKey(storage_id_, _)) 659 .Times(AtLeast(1)) 660 .WillRepeatedly(Return(true)); 661 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite)) 662 .WillOnce(Return(true)); 663 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect)) 664 .WillOnce(Return(true)); 665 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber()); 666 EXPECT_CALL(storage, 667 SetBool(storage_id_, 668 Service::kStorageSaveCredentials, 669 service_->save_credentials())); 670#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 671 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)); 672#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 673 std::unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties()); 674 EXPECT_CALL(*dhcp_props.get(), Save(&storage, storage_id_)); 675 service_->dhcp_properties_ = std::move(dhcp_props); 676 EXPECT_TRUE(service_->Save(&storage)); 677} 678 679TEST_F(ServiceTest, RetainAutoConnect) { 680 NiceMock<MockStore> storage; 681 EXPECT_CALL(storage, SetString(storage_id_, _, _)) 682 .Times(AtLeast(1)) 683 .WillRepeatedly(Return(true)); 684 EXPECT_CALL(storage, DeleteKey(storage_id_, _)) 685 .Times(AtLeast(1)) 686 .WillRepeatedly(Return(true)); 687 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite)) 688 .Times(2); 689 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect)) 690 .Times(0); 691 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber()); 692#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 693 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2); 694#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 695 696 // AutoConnect flag set true. 697 service_->EnableAndRetainAutoConnect(); 698 EXPECT_CALL(storage, 699 SetBool(storage_id_, Service::kStorageAutoConnect, true)); 700 EXPECT_TRUE(service_->Save(&storage)); 701 702 // AutoConnect flag set false. 703 EXPECT_CALL(storage, 704 SetBool(storage_id_, Service::kStorageAutoConnect, false)); 705 service_->SetAutoConnect(false); 706 EXPECT_TRUE(service_->Save(&storage)); 707} 708 709TEST_F(ServiceTest, HasEverConnectedSavedToProfile) { 710 NiceMock<MockStore> storage; 711 EXPECT_CALL(storage, SetString(storage_id_, _, _)) 712 .Times(AtLeast(1)) 713 .WillRepeatedly(Return(true)); 714 EXPECT_CALL(storage, DeleteKey(storage_id_, _)) 715 .Times(AtLeast(1)) 716 .WillRepeatedly(Return(true)); 717 EXPECT_CALL(storage, 718 DeleteKey(storage_id_, Service::kStorageHasEverConnected)) 719 .Times(0); 720 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber()); 721#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 722 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2); 723#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 724 725 // HasEverConnected flag set true. 726 service_->SetHasEverConnected(true); 727 EXPECT_CALL(storage, 728 SetBool(storage_id_, Service::kStorageHasEverConnected, true)); 729 EXPECT_TRUE(service_->Save(&storage)); 730 731 // HasEverConnected flag set false. 732 EXPECT_CALL(storage, 733 SetBool(storage_id_, Service::kStorageHasEverConnected, false)); 734 service_->SetHasEverConnected(false); 735 EXPECT_TRUE(service_->Save(&storage)); 736} 737 738TEST_F(ServiceTest, Unload) { 739 NiceMock<MockStore> storage; 740 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true)); 741 static const string string_value("value"); 742 EXPECT_CALL(storage, GetString(storage_id_, _, _)) 743 .Times(AtLeast(1)) 744 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true))); 745 EXPECT_CALL(storage, GetBool(storage_id_, _, _)) 746 .Times(AtLeast(1)) 747 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true))); 748 EXPECT_FALSE(service_->explicitly_disconnected_); 749 service_->explicitly_disconnected_ = true; 750 EXPECT_FALSE(service_->has_ever_connected_); 751#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 752 EXPECT_CALL(*eap_, Load(&storage, storage_id_)); 753#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 754 ASSERT_TRUE(service_->Load(&storage)); 755 // TODO(pstew): Only two string properties in the service are tested as 756 // a sentinel that properties are being set and reset at the right times. 757 // However, since property load/store is essentially a manual process, 758 // it is error prone and should either be exhaustively unit-tested or 759 // a generic framework for registering loaded/stored properties should 760 // be created. crbug.com/207798 761 EXPECT_EQ(string_value, service_->ui_data_); 762 EXPECT_EQ(string_value, service_->guid_); 763 EXPECT_FALSE(service_->explicitly_disconnected_); 764 EXPECT_TRUE(service_->has_ever_connected_); 765 service_->explicitly_disconnected_ = true; 766#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 767 EXPECT_CALL(*eap_, Reset()); 768#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 769 service_->Unload(); 770 EXPECT_EQ(string(""), service_->ui_data_); 771 EXPECT_EQ(string(""), service_->guid_); 772 EXPECT_FALSE(service_->explicitly_disconnected_); 773 EXPECT_FALSE(service_->has_ever_connected_); 774} 775 776TEST_F(ServiceTest, State) { 777 EXPECT_EQ(Service::kStateIdle, service_->state()); 778 EXPECT_EQ(Service::kStateIdle, GetPreviousState()); 779 EXPECT_EQ(Service::kFailureUnknown, service_->failure()); 780 const string unknown_error( 781 Service::ConnectFailureToString(Service::kFailureUnknown)); 782 EXPECT_EQ(unknown_error, service_->error()); 783 784 EXPECT_CALL(*GetAdaptor(), 785 EmitStringChanged(kStateProperty, _)).Times(6); 786 EXPECT_CALL(*GetAdaptor(), 787 EmitStringChanged(kErrorProperty, _)).Times(4); 788 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 789 service_->SetState(Service::kStateConnected); 790 EXPECT_EQ(Service::kStateIdle, GetPreviousState()); 791 // A second state change shouldn't cause another update 792 service_->SetState(Service::kStateConnected); 793 EXPECT_EQ(Service::kStateConnected, service_->state()); 794 EXPECT_EQ(Service::kStateIdle, GetPreviousState()); 795 EXPECT_EQ(Service::kFailureUnknown, service_->failure()); 796 EXPECT_TRUE(service_->has_ever_connected_); 797 798 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 799 service_->SetFailure(Service::kFailureOutOfRange); 800 EXPECT_TRUE(service_->IsFailed()); 801 EXPECT_GT(service_->failed_time_, 0); 802 EXPECT_GT(service_->previous_error_serial_number_, 0); 803 EXPECT_EQ(Service::kStateFailure, service_->state()); 804 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure()); 805 const string out_of_range_error( 806 Service::ConnectFailureToString(Service::kFailureOutOfRange)); 807 EXPECT_EQ(out_of_range_error, service_->error()); 808 EXPECT_EQ(out_of_range_error, service_->previous_error_); 809 810 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 811 service_->SetState(Service::kStateConnected); 812 EXPECT_FALSE(service_->IsFailed()); 813 EXPECT_EQ(service_->failed_time_, 0); 814 EXPECT_EQ(unknown_error, service_->error()); 815 EXPECT_EQ(out_of_range_error, service_->previous_error_); 816 EXPECT_GT(service_->previous_error_serial_number_, 0); 817 818 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 819 service_->SetFailureSilent(Service::kFailurePinMissing); 820 EXPECT_TRUE(service_->IsFailed()); 821 EXPECT_GT(service_->failed_time_, 0); 822 EXPECT_GT(service_->previous_error_serial_number_, 0); 823 EXPECT_EQ(Service::kStateIdle, service_->state()); 824 EXPECT_EQ(Service::kFailurePinMissing, service_->failure()); 825 const string pin_missing_error( 826 Service::ConnectFailureToString(Service::kFailurePinMissing)); 827 EXPECT_EQ(pin_missing_error, service_->error()); 828 EXPECT_EQ(pin_missing_error, service_->previous_error_); 829 830 // If the Service has a Profile, the profile should be saved when 831 // the service enters kStateConnected. (The case where the service 832 // doesn't have a profile is tested above.) 833 MockProfileRefPtr mock_profile( 834 new MockProfile(control_interface(), metrics(), &mock_manager_)); 835 NiceMock<MockStore> storage; 836 service_->set_profile(mock_profile); 837 service_->has_ever_connected_ = false; 838 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 839 EXPECT_CALL(*mock_profile, GetConstStorage()) 840 .WillOnce(Return(&storage)); 841 EXPECT_CALL(*mock_profile, UpdateService(IsRefPtrTo(service_))); 842 service_->SetState(Service::kStateConnected); 843 EXPECT_TRUE(service_->has_ever_connected_); 844 service_->set_profile(nullptr); // Break reference cycle. 845 846 // Similar to the above, but emulate an emphemeral profile, which 847 // has no storage. We can't update the service in the profile, but 848 // we should not crash. 849 service_->state_ = Service::kStateIdle; // Skips state change logic. 850 service_->set_profile(mock_profile); 851 service_->has_ever_connected_ = false; 852 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 853 EXPECT_CALL(*mock_profile, GetConstStorage()).WillOnce(Return(nullptr)); 854 service_->SetState(Service::kStateConnected); 855 EXPECT_TRUE(service_->has_ever_connected_); 856 service_->set_profile(nullptr); // Break reference cycle. 857} 858 859TEST_F(ServiceTest, PortalDetectionFailure) { 860 EXPECT_CALL(*GetAdaptor(), 861 EmitStringChanged(kPortalDetectionFailedPhaseProperty, 862 kPortalDetectionPhaseDns)).Times(1); 863 EXPECT_CALL(*GetAdaptor(), 864 EmitStringChanged(kPortalDetectionFailedStatusProperty, 865 kPortalDetectionStatusTimeout)).Times(1); 866 service_->SetPortalDetectionFailure(kPortalDetectionPhaseDns, 867 kPortalDetectionStatusTimeout); 868 EXPECT_EQ(kPortalDetectionPhaseDns, 869 service_->portal_detection_failure_phase_); 870 EXPECT_EQ(kPortalDetectionStatusTimeout, 871 service_->portal_detection_failure_status_); 872} 873 874TEST_F(ServiceTest, StateResetAfterFailure) { 875 service_->SetFailure(Service::kFailureOutOfRange); 876 EXPECT_EQ(Service::kStateFailure, service_->state()); 877 Error error; 878 service_->Connect(&error, "in test"); 879 EXPECT_EQ(Service::kStateIdle, service_->state()); 880 EXPECT_EQ(Service::kFailureUnknown, service_->failure()); 881 882 service_->SetState(Service::kStateConnected); 883 service_->Connect(&error, "in test"); 884 EXPECT_EQ(Service::kStateConnected, service_->state()); 885} 886 887TEST_F(ServiceTest, UserInitiatedConnectionResult) { 888 service_->technology_ = Technology::kWifi; 889 Error error; 890 // User-initiated connection attempt succeed. 891 service_->SetState(Service::kStateIdle); 892 service_->UserInitiatedConnect(&error); 893 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult( 894 Metrics::kMetricWifiUserInitiatedConnectionResult, 895 Metrics::kUserInitiatedConnectionResultSuccess)); 896 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _)) 897 .Times(0); 898 service_->SetState(Service::kStateConnected); 899 Mock::VerifyAndClearExpectations(metrics()); 900 901 // User-initiated connection attempt failed. 902 service_->SetState(Service::kStateIdle); 903 service_->UserInitiatedConnect(&error); 904 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult( 905 Metrics::kMetricWifiUserInitiatedConnectionResult, 906 Metrics::kUserInitiatedConnectionResultFailure)); 907 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason( 908 Metrics::kMetricWifiUserInitiatedConnectionFailureReason, 909 Service::kFailureDHCP)); 910 service_->SetFailure(Service::kFailureDHCP); 911 Mock::VerifyAndClearExpectations(metrics()); 912 913 // User-initiated connection attempt aborted. 914 service_->SetState(Service::kStateIdle); 915 service_->UserInitiatedConnect(&error); 916 service_->SetState(Service::kStateAssociating); 917 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult( 918 Metrics::kMetricWifiUserInitiatedConnectionResult, 919 Metrics::kUserInitiatedConnectionResultAborted)); 920 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _)) 921 .Times(0); 922 service_->SetState(Service::kStateIdle); 923 Mock::VerifyAndClearExpectations(metrics()); 924 925 // No metric reporting for other state transition. 926 service_->SetState(Service::kStateIdle); 927 service_->UserInitiatedConnect(&error); 928 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0); 929 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _)) 930 .Times(0); 931 service_->SetState(Service::kStateAssociating); 932 service_->SetState(Service::kStateConfiguring); 933 Mock::VerifyAndClearExpectations(metrics()); 934 935 // No metric reporting for non-user-initiated connection. 936 service_->SetState(Service::kStateIdle); 937 service_->Connect(&error, "in test"); 938 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0); 939 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _)) 940 .Times(0); 941 service_->SetState(Service::kStateConnected); 942 Mock::VerifyAndClearExpectations(metrics()); 943 944 // No metric reporting for other technology. 945 service_->technology_ = Technology::kCellular; 946 service_->SetState(Service::kStateIdle); 947 service_->UserInitiatedConnect(&error); 948 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0); 949 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _)) 950 .Times(0); 951 service_->SetFailure(Service::kFailureDHCP); 952 Mock::VerifyAndClearExpectations(metrics()); 953} 954 955TEST_F(ServiceTest, ActivateCellularModem) { 956 ResultCallback callback = 957 Bind(&ServiceTest::TestCallback, Unretained(this)); 958 EXPECT_CALL(*this, TestCallback(_)).Times(0); 959 Error error; 960 service_->ActivateCellularModem("Carrier", &error, callback); 961 EXPECT_TRUE(error.IsFailure()); 962} 963 964TEST_F(ServiceTest, CompleteCellularActivation) { 965 Error error; 966 service_->CompleteCellularActivation(&error); 967 EXPECT_EQ(Error::kNotSupported, error.type()); 968} 969 970TEST_F(ServiceTest, EnableAndRetainAutoConnect) { 971 EXPECT_FALSE(service_->retain_auto_connect()); 972 EXPECT_FALSE(service_->auto_connect()); 973 974 service_->EnableAndRetainAutoConnect(); 975 EXPECT_TRUE(service_->retain_auto_connect()); 976 EXPECT_TRUE(service_->auto_connect()); 977} 978 979TEST_F(ServiceTest, ReRetainAutoConnect) { 980 service_->EnableAndRetainAutoConnect(); 981 EXPECT_TRUE(service_->retain_auto_connect()); 982 EXPECT_TRUE(service_->auto_connect()); 983 984 service_->SetAutoConnect(false); 985 service_->EnableAndRetainAutoConnect(); 986 EXPECT_TRUE(service_->retain_auto_connect()); 987 EXPECT_FALSE(service_->auto_connect()); 988} 989 990TEST_F(ServiceTest, IsAutoConnectable) { 991 const char* reason = nullptr; 992 service_->SetConnectable(true); 993 994 // Services with non-primary connectivity technologies should not auto-connect 995 // when the system is offline. 996 EXPECT_EQ(Technology::kUnknown, service_->technology()); 997 EXPECT_CALL(mock_manager_, IsConnected()).WillOnce(Return(false)); 998 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 999 EXPECT_STREQ(Service::kAutoConnOffline, reason); 1000 1001 service_->technology_ = Technology::kEthernet; 1002 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1003 1004 // We should not auto-connect to a Service that a user has 1005 // deliberately disconnected. 1006 Error error; 1007 service_->UserInitiatedDisconnect(&error); 1008 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1009 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason); 1010 1011 // But if the Service is reloaded, it is eligible for auto-connect 1012 // again. 1013 NiceMock<MockStore> storage; 1014 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true)); 1015#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 1016 EXPECT_CALL(*eap_, Load(&storage, storage_id_)); 1017#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 1018 EXPECT_TRUE(service_->Load(&storage)); 1019 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1020 1021 // A deliberate Connect should also re-enable auto-connect. 1022 service_->UserInitiatedDisconnect(&error); 1023 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1024 service_->Connect(&error, "in test"); 1025 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1026 1027 // A non-user initiated Disconnect doesn't change anything. 1028 service_->Disconnect(&error, "in test"); 1029 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1030 1031 // A resume also re-enables auto-connect. 1032 service_->UserInitiatedDisconnect(&error); 1033 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1034 service_->OnAfterResume(); 1035 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1036 1037 service_->SetState(Service::kStateConnected); 1038 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1039 EXPECT_STREQ(Service::kAutoConnConnected, reason); 1040 1041 service_->SetState(Service::kStateAssociating); 1042 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1043 EXPECT_STREQ(Service::kAutoConnConnecting, reason); 1044 1045 service_->SetState(Service::kStateIdle); 1046 EXPECT_CALL(mock_manager_, IsTechnologyAutoConnectDisabled( 1047 service_->technology_)).WillOnce(Return(true)); 1048 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1049 EXPECT_STREQ(Service::kAutoConnTechnologyNotConnectable, reason); 1050} 1051 1052TEST_F(ServiceTest, AutoConnectLogging) { 1053 ScopedMockLog log; 1054 EXPECT_CALL(log, Log(_, _, _)); 1055 service_->SetConnectable(true); 1056 1057 ScopeLogger::GetInstance()->EnableScopesByName("+service"); 1058 ScopeLogger::GetInstance()->set_verbose_level(1); 1059 service_->SetState(Service::kStateConnected); 1060 EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected))); 1061 service_->AutoConnect(); 1062 1063 ScopeLogger::GetInstance()->EnableScopesByName("-service"); 1064 ScopeLogger::GetInstance()->set_verbose_level(0); 1065 EXPECT_CALL(log, Log(logging::LOG_INFO, _, 1066 HasSubstr(Service::kAutoConnNotConnectable))); 1067 service_->SetConnectable(false); 1068 service_->AutoConnect(); 1069} 1070 1071 1072TEST_F(AllMockServiceTest, AutoConnectWithFailures) { 1073 const char* reason; 1074 service_->SetConnectable(true); 1075 service_->technology_ = Technology::kEthernet; 1076 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1077 1078 // The very first AutoConnect() doesn't trigger any throttling. 1079 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0); 1080 service_->AutoConnect(); 1081 Mock::VerifyAndClearExpectations(&dispatcher_); 1082 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1083 1084 // The second call does trigger some throttling. 1085 EXPECT_CALL(dispatcher_, PostDelayedTask(_, 1086 Service::kMinAutoConnectCooldownTimeMilliseconds)); 1087 service_->AutoConnect(); 1088 Mock::VerifyAndClearExpectations(&dispatcher_); 1089 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1090 EXPECT_STREQ(Service::kAutoConnThrottled, reason); 1091 1092 // Calling AutoConnect() again before the cooldown terminates does not change 1093 // the timeout. 1094 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0); 1095 service_->AutoConnect(); 1096 Mock::VerifyAndClearExpectations(&dispatcher_); 1097 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1098 EXPECT_STREQ(Service::kAutoConnThrottled, reason); 1099 1100 // Once the timeout expires, we can AutoConnect() again. 1101 service_->ReEnableAutoConnectTask(); 1102 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1103 1104 // Timeouts increase exponentially. 1105 uint64_t next_cooldown_time = service_->auto_connect_cooldown_milliseconds_; 1106 EXPECT_EQ(next_cooldown_time, 1107 Service::kAutoConnectCooldownBackoffFactor * 1108 Service::kMinAutoConnectCooldownTimeMilliseconds); 1109 while (next_cooldown_time <= 1110 Service::kMaxAutoConnectCooldownTimeMilliseconds) { 1111 EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time)); 1112 service_->AutoConnect(); 1113 Mock::VerifyAndClearExpectations(&dispatcher_); 1114 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1115 EXPECT_STREQ(Service::kAutoConnThrottled, reason); 1116 service_->ReEnableAutoConnectTask(); 1117 next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor; 1118 } 1119 1120 // Once we hit our cap, future timeouts are the same. 1121 for (int32_t i = 0; i < 2; i++) { 1122 EXPECT_CALL(dispatcher_, PostDelayedTask(_, 1123 Service::kMaxAutoConnectCooldownTimeMilliseconds)); 1124 service_->AutoConnect(); 1125 Mock::VerifyAndClearExpectations(&dispatcher_); 1126 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1127 EXPECT_STREQ(Service::kAutoConnThrottled, reason); 1128 service_->ReEnableAutoConnectTask(); 1129 } 1130 1131 // Connecting successfully resets our cooldown. 1132 service_->SetState(Service::kStateConnected); 1133 service_->SetState(Service::kStateIdle); 1134 reason = ""; 1135 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1136 EXPECT_STREQ("", reason); 1137 EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0); 1138 1139 // But future AutoConnects behave as before 1140 EXPECT_CALL(dispatcher_, PostDelayedTask(_, 1141 Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1); 1142 service_->AutoConnect(); 1143 service_->AutoConnect(); 1144 Mock::VerifyAndClearExpectations(&dispatcher_); 1145 EXPECT_FALSE(service_->IsAutoConnectable(&reason)); 1146 EXPECT_STREQ(Service::kAutoConnThrottled, reason); 1147 1148 // Cooldowns are forgotten if we go through a suspend/resume cycle. 1149 service_->OnAfterResume(); 1150 reason = ""; 1151 EXPECT_TRUE(service_->IsAutoConnectable(&reason)); 1152 EXPECT_STREQ("", reason); 1153} 1154 1155TEST_F(ServiceTest, ConfigureBadProperty) { 1156 KeyValueStore args; 1157 args.SetString("XXXInvalid", "Value"); 1158 Error error; 1159 service_->Configure(args, &error); 1160 EXPECT_FALSE(error.IsSuccess()); 1161} 1162 1163TEST_F(ServiceTest, ConfigureBoolProperty) { 1164 service_->EnableAndRetainAutoConnect(); 1165 service_->SetAutoConnect(false); 1166 ASSERT_FALSE(service_->auto_connect()); 1167 KeyValueStore args; 1168 args.SetBool(kAutoConnectProperty, true); 1169 Error error; 1170 service_->Configure(args, &error); 1171 EXPECT_TRUE(error.IsSuccess()); 1172 EXPECT_TRUE(service_->auto_connect()); 1173} 1174 1175TEST_F(ServiceTest, ConfigureStringProperty) { 1176 const string kGuid0 = "guid_zero"; 1177 const string kGuid1 = "guid_one"; 1178 service_->SetGuid(kGuid0, nullptr); 1179 ASSERT_EQ(kGuid0, service_->guid()); 1180 KeyValueStore args; 1181 args.SetString(kGuidProperty, kGuid1); 1182 Error error; 1183 service_->Configure(args, &error); 1184 EXPECT_TRUE(error.IsSuccess()); 1185 EXPECT_EQ(kGuid1, service_->guid()); 1186} 1187 1188TEST_F(ServiceTest, ConfigureStringsProperty) { 1189 const vector<string> kStrings0{ "string0", "string1" }; 1190 const vector<string> kStrings1{ "string2", "string3" }; 1191 service_->set_strings(kStrings0); 1192 ASSERT_EQ(kStrings0, service_->strings()); 1193 KeyValueStore args; 1194 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1); 1195 Error error; 1196 service_->Configure(args, &error); 1197 EXPECT_TRUE(error.IsSuccess()); 1198 EXPECT_EQ(kStrings1, service_->strings()); 1199} 1200 1201#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 1202TEST_F(ServiceTest, ConfigureEapStringProperty) { 1203 MockEapCredentials* eap = new MockEapCredentials(); 1204 service2_->SetEapCredentials(eap); // Passes ownership. 1205 1206 const string kEAPManagement0 = "management_zero"; 1207 const string kEAPManagement1 = "management_one"; 1208 service2_->SetEAPKeyManagement(kEAPManagement0); 1209 1210 EXPECT_CALL(*eap, key_management()) 1211 .WillOnce(ReturnRef(kEAPManagement0)); 1212 ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement()); 1213 KeyValueStore args; 1214 EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _)); 1215 args.SetString(kEapKeyMgmtProperty, kEAPManagement1); 1216 Error error; 1217 service2_->Configure(args, &error); 1218 EXPECT_TRUE(error.IsSuccess()); 1219} 1220#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 1221 1222TEST_F(ServiceTest, ConfigureIntProperty) { 1223 const int kPriority0 = 100; 1224 const int kPriority1 = 200; 1225 service_->SetPriority(kPriority0, nullptr); 1226 ASSERT_EQ(kPriority0, service_->priority()); 1227 KeyValueStore args; 1228 args.SetInt(kPriorityProperty, kPriority1); 1229 Error error; 1230 service_->Configure(args, &error); 1231 EXPECT_TRUE(error.IsSuccess()); 1232 EXPECT_EQ(kPriority1, service_->priority()); 1233} 1234 1235TEST_F(ServiceTest, ConfigureIgnoredProperty) { 1236 service_->EnableAndRetainAutoConnect(); 1237 service_->SetAutoConnect(false); 1238 ASSERT_FALSE(service_->auto_connect()); 1239 KeyValueStore args; 1240 args.SetBool(kAutoConnectProperty, true); 1241 Error error; 1242 service_->IgnoreParameterForConfigure(kAutoConnectProperty); 1243 service_->Configure(args, &error); 1244 EXPECT_TRUE(error.IsSuccess()); 1245 EXPECT_FALSE(service_->auto_connect()); 1246} 1247 1248TEST_F(ServiceTest, ConfigureProfileProperty) { 1249 // Ensure that the Profile property is always ignored. 1250 KeyValueStore args; 1251 args.SetString(kProfileProperty, "profile"); 1252 Error error; 1253 EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0); 1254 service_->Configure(args, &error); 1255 EXPECT_TRUE(error.IsSuccess()); 1256} 1257 1258TEST_F(ServiceTest, ConfigureKeyValueStoreProperty) { 1259 KeyValueStore key_value_store0; 1260 key_value_store0.SetBool("key0", true); 1261 KeyValueStore key_value_store1; 1262 key_value_store1.SetInt("key1", 1); 1263 service_->SetKeyValueStore(key_value_store0, NULL); 1264 ASSERT_EQ(key_value_store0, service_->GetKeyValueStore(NULL)); 1265 KeyValueStore args; 1266 args.SetKeyValueStore( 1267 ServiceUnderTest::kKeyValueStoreProperty, key_value_store1); 1268 Error error; 1269 service_->Configure(args, &error); 1270 EXPECT_TRUE(error.IsSuccess()); 1271 EXPECT_EQ(key_value_store1, service_->GetKeyValueStore(NULL)); 1272} 1273 1274TEST_F(ServiceTest, DoPropertiesMatch) { 1275 service_->SetAutoConnect(false); 1276 const string kGUID0 = "guid_zero"; 1277 const string kGUID1 = "guid_one"; 1278 service_->SetGuid(kGUID0, nullptr); 1279 const uint32_t kPriority0 = 100; 1280 const uint32_t kPriority1 = 200; 1281 service_->SetPriority(kPriority0, nullptr); 1282 const vector<string> kStrings0{ "string0", "string1" }; 1283 const vector<string> kStrings1{ "string2", "string3" }; 1284 service_->set_strings(kStrings0); 1285 KeyValueStore key_value_store0; 1286 key_value_store0.SetBool("key0", true); 1287 KeyValueStore key_value_store1; 1288 key_value_store1.SetInt("key1", 1); 1289 service_->SetKeyValueStore(key_value_store0, NULL); 1290 1291 { 1292 KeyValueStore args; 1293 args.SetString(kGuidProperty, kGUID0); 1294 args.SetBool(kAutoConnectProperty, false); 1295 args.SetInt(kPriorityProperty, kPriority0); 1296 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0); 1297 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1298 key_value_store0); 1299 EXPECT_TRUE(service_->DoPropertiesMatch(args)); 1300 } 1301 { 1302 KeyValueStore args; 1303 args.SetString(kGuidProperty, kGUID1); 1304 args.SetBool(kAutoConnectProperty, false); 1305 args.SetInt(kPriorityProperty, kPriority0); 1306 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0); 1307 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1308 key_value_store0); 1309 EXPECT_FALSE(service_->DoPropertiesMatch(args)); 1310 } 1311 { 1312 KeyValueStore args; 1313 args.SetString(kGuidProperty, kGUID0); 1314 args.SetBool(kAutoConnectProperty, true); 1315 args.SetInt(kPriorityProperty, kPriority0); 1316 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0); 1317 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1318 key_value_store0); 1319 EXPECT_FALSE(service_->DoPropertiesMatch(args)); 1320 } 1321 { 1322 KeyValueStore args; 1323 args.SetString(kGuidProperty, kGUID0); 1324 args.SetBool(kAutoConnectProperty, false); 1325 args.SetInt(kPriorityProperty, kPriority1); 1326 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0); 1327 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1328 key_value_store0); 1329 EXPECT_FALSE(service_->DoPropertiesMatch(args)); 1330 } 1331 { 1332 KeyValueStore args; 1333 args.SetString(kGuidProperty, kGUID0); 1334 args.SetBool(kAutoConnectProperty, false); 1335 args.SetInt(kPriorityProperty, kPriority0); 1336 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1); 1337 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1338 key_value_store0); 1339 EXPECT_FALSE(service_->DoPropertiesMatch(args)); 1340 } 1341 { 1342 KeyValueStore args; 1343 args.SetString(kGuidProperty, kGUID0); 1344 args.SetBool(kAutoConnectProperty, false); 1345 args.SetInt(kPriorityProperty, kPriority0); 1346 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0); 1347 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty, 1348 key_value_store1); 1349 EXPECT_FALSE(service_->DoPropertiesMatch(args)); 1350 } 1351} 1352 1353TEST_F(ServiceTest, IsRemembered) { 1354 service_->set_profile(nullptr); 1355 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0); 1356 EXPECT_FALSE(service_->IsRemembered()); 1357 1358 scoped_refptr<MockProfile> profile( 1359 new StrictMock<MockProfile>(control_interface(), metrics(), manager())); 1360 service_->set_profile(profile); 1361 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_))) 1362 .WillOnce(Return(true)) 1363 .WillOnce(Return(false)); 1364 EXPECT_FALSE(service_->IsRemembered()); 1365 EXPECT_TRUE(service_->IsRemembered()); 1366} 1367 1368TEST_F(ServiceTest, IsDependentOn) { 1369 EXPECT_FALSE(service_->IsDependentOn(nullptr)); 1370 1371 std::unique_ptr<MockDeviceInfo> mock_device_info( 1372 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(), 1373 &mock_manager_)); 1374 scoped_refptr<MockConnection> mock_connection0( 1375 new NiceMock<MockConnection>(mock_device_info.get())); 1376 scoped_refptr<MockConnection> mock_connection1( 1377 new NiceMock<MockConnection>(mock_device_info.get())); 1378 1379 service_->connection_ = mock_connection0; 1380 EXPECT_CALL(*mock_connection0, GetLowerConnection()) 1381 .WillRepeatedly(Return(mock_connection1)); 1382 EXPECT_CALL(*mock_connection1, GetLowerConnection()) 1383 .WillRepeatedly(Return(ConnectionRefPtr())); 1384 EXPECT_FALSE(service_->IsDependentOn(nullptr)); 1385 1386 scoped_refptr<ServiceUnderTest> service1 = 1387 new ServiceUnderTest(control_interface(), 1388 dispatcher(), 1389 metrics(), 1390 &mock_manager_); 1391 EXPECT_FALSE(service_->IsDependentOn(service1)); 1392 1393 service1->connection_ = mock_connection0; 1394 EXPECT_FALSE(service_->IsDependentOn(service1)); 1395 1396 service1->connection_ = mock_connection1; 1397 EXPECT_TRUE(service_->IsDependentOn(service1)); 1398 1399 service_->connection_ = mock_connection1; 1400 service1->connection_ = nullptr; 1401 EXPECT_FALSE(service_->IsDependentOn(service1)); 1402 1403 service_->connection_ = nullptr; 1404} 1405 1406TEST_F(ServiceTest, OnPropertyChanged) { 1407 scoped_refptr<MockProfile> profile( 1408 new StrictMock<MockProfile>(control_interface(), metrics(), manager())); 1409 service_->set_profile(nullptr); 1410 // Expect no crash. 1411 service_->OnPropertyChanged(""); 1412 1413 // Expect no call to Update if the profile has no storage. 1414 service_->set_profile(profile); 1415 EXPECT_CALL(*profile, UpdateService(_)).Times(0); 1416 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(nullptr)); 1417 service_->OnPropertyChanged(""); 1418 1419 // Expect call to Update if the profile has storage. 1420 EXPECT_CALL(*profile, UpdateService(_)).Times(1); 1421 NiceMock<MockStore> storage; 1422 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage)); 1423 service_->OnPropertyChanged(""); 1424} 1425 1426 1427TEST_F(ServiceTest, RecheckPortal) { 1428 service_->state_ = Service::kStateIdle; 1429 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0); 1430 service_->OnPropertyChanged(kCheckPortalProperty); 1431 1432 service_->state_ = Service::kStatePortal; 1433 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_))) 1434 .Times(1); 1435 service_->OnPropertyChanged(kCheckPortalProperty); 1436 1437 service_->state_ = Service::kStateConnected; 1438 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_))) 1439 .Times(1); 1440 service_->OnPropertyChanged(kProxyConfigProperty); 1441 1442 service_->state_ = Service::kStateOnline; 1443 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_))) 1444 .Times(1); 1445 service_->OnPropertyChanged(kCheckPortalProperty); 1446 1447 service_->state_ = Service::kStatePortal; 1448 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0); 1449 service_->OnPropertyChanged(kEapKeyIdProperty); 1450} 1451 1452TEST_F(ServiceTest, SetCheckPortal) { 1453 { 1454 Error error; 1455 service_->SetCheckPortal("false", &error); 1456 EXPECT_TRUE(error.IsSuccess()); 1457 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_); 1458 } 1459 { 1460 Error error; 1461 service_->SetCheckPortal("true", &error); 1462 EXPECT_TRUE(error.IsSuccess()); 1463 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_); 1464 } 1465 { 1466 Error error; 1467 service_->SetCheckPortal("auto", &error); 1468 EXPECT_TRUE(error.IsSuccess()); 1469 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_); 1470 } 1471 { 1472 Error error; 1473 service_->SetCheckPortal("xxx", &error); 1474 EXPECT_FALSE(error.IsSuccess()); 1475 EXPECT_EQ(Error::kInvalidArguments, error.type()); 1476 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_); 1477 } 1478} 1479 1480TEST_F(ServiceTest, SetFriendlyName) { 1481 EXPECT_EQ(service_->unique_name_, service_->friendly_name_); 1482 ServiceMockAdaptor* adaptor = GetAdaptor(); 1483 1484 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0); 1485 service_->SetFriendlyName(service_->unique_name_); 1486 EXPECT_EQ(service_->unique_name_, service_->friendly_name_); 1487 1488 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty, 1489 "Test Name 1")); 1490 service_->SetFriendlyName("Test Name 1"); 1491 EXPECT_EQ("Test Name 1", service_->friendly_name_); 1492 1493 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0); 1494 service_->SetFriendlyName("Test Name 1"); 1495 EXPECT_EQ("Test Name 1", service_->friendly_name_); 1496 1497 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty, 1498 "Test Name 2")); 1499 service_->SetFriendlyName("Test Name 2"); 1500 EXPECT_EQ("Test Name 2", service_->friendly_name_); 1501} 1502 1503TEST_F(ServiceTest, SetConnectableFull) { 1504 EXPECT_FALSE(service_->connectable()); 1505 1506 ServiceMockAdaptor* adaptor = GetAdaptor(); 1507 1508 EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0); 1509 EXPECT_CALL(mock_manager_, HasService(_)).Times(0); 1510 service_->SetConnectableFull(false); 1511 EXPECT_FALSE(service_->connectable()); 1512 1513 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true)); 1514 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false)); 1515 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 1516 service_->SetConnectableFull(true); 1517 EXPECT_TRUE(service_->connectable()); 1518 1519 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, false)); 1520 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true)); 1521 EXPECT_CALL(mock_manager_, UpdateService(_)); 1522 service_->SetConnectableFull(false); 1523 EXPECT_FALSE(service_->connectable()); 1524 1525 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true)); 1526 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true)); 1527 EXPECT_CALL(mock_manager_, UpdateService(_)); 1528 service_->SetConnectableFull(true); 1529 EXPECT_TRUE(service_->connectable()); 1530} 1531 1532#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 1533class WriteOnlyServicePropertyTest : public ServiceTest {}; 1534TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) { 1535 // Use a real EapCredentials instance since the base Service class 1536 // contains no write-only properties. 1537 EapCredentials eap; 1538 eap.InitPropertyStore(service_->mutable_store()); 1539 1540 string property(GetParam().Get<string>()); 1541 Error error; 1542 EXPECT_FALSE(service_->store().GetStringProperty(property, nullptr, &error)); 1543 EXPECT_EQ(Error::kPermissionDenied, error.type()); 1544} 1545 1546INSTANTIATE_TEST_CASE_P( 1547 WriteOnlyServicePropertyTestInstance, 1548 WriteOnlyServicePropertyTest, 1549 Values( 1550 brillo::Any(string(kEapPrivateKeyPasswordProperty)), 1551 brillo::Any(string(kEapPasswordProperty)))); 1552#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 1553 1554TEST_F(ServiceTest, GetIPConfigRpcIdentifier) { 1555 { 1556 Error error; 1557 EXPECT_EQ(control_interface()->NullRPCIdentifier(), 1558 service_->GetIPConfigRpcIdentifier(&error)); 1559 EXPECT_EQ(Error::kNotFound, error.type()); 1560 } 1561 1562 std::unique_ptr<MockDeviceInfo> mock_device_info( 1563 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(), 1564 &mock_manager_)); 1565 scoped_refptr<MockConnection> mock_connection( 1566 new NiceMock<MockConnection>(mock_device_info.get())); 1567 1568 service_->connection_ = mock_connection; 1569 1570 { 1571 Error error; 1572 const string empty_string; 1573 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier()) 1574 .WillOnce(ReturnRef(empty_string)); 1575 EXPECT_EQ(control_interface()->NullRPCIdentifier(), 1576 service_->GetIPConfigRpcIdentifier(&error)); 1577 EXPECT_EQ(Error::kNotFound, error.type()); 1578 } 1579 1580 { 1581 Error error; 1582 const string nonempty_string("/ipconfig/path"); 1583 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier()) 1584 .WillOnce(ReturnRef(nonempty_string)); 1585 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error)); 1586 EXPECT_EQ(Error::kSuccess, error.type()); 1587 } 1588 1589 // Assure orderly destruction of the Connection before DeviceInfo. 1590 service_->connection_ = nullptr; 1591 mock_connection = nullptr; 1592 mock_device_info.reset(); 1593} 1594 1595#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X) 1596class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest { 1597 public: 1598 ServiceWithMockOnEapCredentialsChanged(ControlInterface* control_interface, 1599 EventDispatcher* dispatcher, 1600 Metrics* metrics, 1601 Manager* manager) 1602 : ServiceUnderTest(control_interface, dispatcher, metrics, manager), 1603 is_8021x_(false) {} 1604 MOCK_METHOD1(OnEapCredentialsChanged, void(Service::UpdateCredentialsReason)); 1605 virtual bool Is8021x() const { return is_8021x_; } 1606 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; } 1607 1608 private: 1609 bool is_8021x_; 1610}; 1611 1612TEST_F(ServiceTest, SetEAPCredentialsOverRPC) { 1613 scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service( 1614 new ServiceWithMockOnEapCredentialsChanged(control_interface(), 1615 dispatcher(), 1616 metrics(), 1617 &mock_manager_)); 1618 string eap_credential_properties[] = { 1619 kEapAnonymousIdentityProperty, 1620 kEapCertIdProperty, 1621 kEapClientCertProperty, 1622 kEapIdentityProperty, 1623 kEapKeyIdProperty, 1624 kEapPasswordProperty, 1625 kEapPinProperty, 1626 kEapPrivateKeyProperty, 1627 kEapPrivateKeyPasswordProperty 1628 }; 1629 string eap_non_credential_properties[] = { 1630 kEapCaCertIdProperty, 1631 kEapCaCertNssProperty, 1632 kEapMethodProperty, 1633 kEapPhase2AuthProperty, 1634 kEapUseSystemCasProperty 1635 }; 1636 // While this is not an 802.1x-based service, none of these property 1637 // changes should cause a call to set_eap(). 1638 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0); 1639 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) 1640 service->OnPropertyChanged(eap_credential_properties[i]); 1641 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i) 1642 service->OnPropertyChanged(eap_non_credential_properties[i]); 1643 service->OnPropertyChanged(kEapKeyMgmtProperty); 1644 1645 service->set_is_8021x(true); 1646 1647 // When this is an 802.1x-based service, set_eap should be called for 1648 // all credential-carrying properties. 1649 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) { 1650 EXPECT_CALL(*service, 1651 OnEapCredentialsChanged( 1652 Service::kReasonPropertyUpdate)).Times(1); 1653 service->OnPropertyChanged(eap_credential_properties[i]); 1654 Mock::VerifyAndClearExpectations(service.get()); 1655 } 1656 1657 // The key management property is a special case. While not strictly 1658 // a credential, it can change which credentials are used. Therefore it 1659 // should also trigger a call to set_eap(); 1660 EXPECT_CALL(*service, 1661 OnEapCredentialsChanged(Service::kReasonPropertyUpdate)).Times(1); 1662 service->OnPropertyChanged(kEapKeyMgmtProperty); 1663 Mock::VerifyAndClearExpectations(service.get()); 1664 1665 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0); 1666 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i) 1667 service->OnPropertyChanged(eap_non_credential_properties[i]); 1668} 1669 1670TEST_F(ServiceTest, Certification) { 1671 EXPECT_FALSE(service_->remote_certification_.size()); 1672 1673 ScopedMockLog log; 1674 EXPECT_CALL(log, Log(logging::LOG_WARNING, _, 1675 HasSubstr("exceeds our maximum"))).Times(2); 1676 string kSubject("foo"); 1677 EXPECT_FALSE(service_->AddEAPCertification( 1678 kSubject, Service::kEAPMaxCertificationElements)); 1679 EXPECT_FALSE(service_->AddEAPCertification( 1680 kSubject, Service::kEAPMaxCertificationElements + 1)); 1681 EXPECT_FALSE(service_->remote_certification_.size()); 1682 Mock::VerifyAndClearExpectations(&log); 1683 1684 EXPECT_CALL(log, 1685 Log(logging::LOG_INFO, _, HasSubstr("Received certification"))) 1686 .Times(1); 1687 EXPECT_TRUE(service_->AddEAPCertification( 1688 kSubject, Service::kEAPMaxCertificationElements - 1)); 1689 Mock::VerifyAndClearExpectations(&log); 1690 EXPECT_EQ(Service::kEAPMaxCertificationElements, 1691 service_->remote_certification_.size()); 1692 for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) { 1693 EXPECT_TRUE(service_->remote_certification_[i].empty()); 1694 } 1695 EXPECT_EQ(kSubject, service_->remote_certification_[ 1696 Service::kEAPMaxCertificationElements - 1]); 1697 1698 // Re-adding the same name in the same position should not generate a log. 1699 EXPECT_CALL(log, Log(_, _, _)).Times(0); 1700 EXPECT_TRUE(service_->AddEAPCertification( 1701 kSubject, Service::kEAPMaxCertificationElements - 1)); 1702 1703 // Replacing the item should generate a log message. 1704 EXPECT_CALL(log, 1705 Log(logging::LOG_INFO, _, HasSubstr("Received certification"))) 1706 .Times(1); 1707 EXPECT_TRUE(service_->AddEAPCertification( 1708 kSubject + "x", Service::kEAPMaxCertificationElements - 1)); 1709 1710 service_->ClearEAPCertification(); 1711 EXPECT_TRUE(service_->remote_certification_.empty()); 1712} 1713#endif // DISABLE_WIFI || DISABLE_WIRED_8021X 1714 1715TEST_F(ServiceTest, NoteDisconnectEventIdle) { 1716 Timestamp timestamp; 1717 EXPECT_CALL(time_, GetNow()).Times(7).WillRepeatedly((Return(timestamp))); 1718 SetStateField(Service::kStateOnline); 1719 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1720 service_->SetState(Service::kStateIdle); 1721 // The transition Online->Idle is not an event. 1722 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1723 service_->SetState(Service::kStateFailure); 1724 // The transition Online->Idle->Failure is a connection drop. 1725 EXPECT_TRUE(service_->HasRecentConnectionIssues()); 1726} 1727 1728TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) { 1729 Timestamp timestamp; 1730 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp))); 1731 SetStateField(Service::kStateOnline); 1732 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1733 service_->SetState(Service::kStateFailure); 1734 EXPECT_TRUE(service_->HasRecentConnectionIssues()); 1735} 1736 1737TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) { 1738 Timestamp timestamp; 1739 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp))); 1740 SetStateField(Service::kStateConfiguring); 1741 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1742 service_->SetFailureSilent(Service::kFailureEAPAuthentication); 1743 EXPECT_TRUE(service_->HasRecentConnectionIssues()); 1744} 1745 1746TEST_F(ServiceTest, NoteDisconnectEventNonEvent) { 1747 EXPECT_CALL(time_, GetNow()).Times(0); 1748 1749 // Explicit disconnect is a non-event. 1750 SetStateField(Service::kStateOnline); 1751 SetExplicitlyDisconnected(true); 1752 NoteDisconnectEvent(); 1753 EXPECT_TRUE(GetDisconnects()->Empty()); 1754 EXPECT_TRUE(GetMisconnects()->Empty()); 1755 1756 // Failure to idle transition is a non-event. 1757 SetStateField(Service::kStateFailure); 1758 SetExplicitlyDisconnected(false); 1759 NoteDisconnectEvent(); 1760 EXPECT_TRUE(GetDisconnects()->Empty()); 1761 EXPECT_TRUE(GetMisconnects()->Empty()); 1762 1763 // Disconnect while manager is stopped is a non-event. 1764 SetStateField(Service::kStateOnline); 1765 SetManagerRunning(false); 1766 NoteDisconnectEvent(); 1767 EXPECT_TRUE(GetDisconnects()->Empty()); 1768 EXPECT_TRUE(GetMisconnects()->Empty()); 1769 1770 // Disconnect while suspending is a non-event. 1771 SetManagerRunning(true); 1772 SetSuspending(true); 1773 NoteDisconnectEvent(); 1774 EXPECT_TRUE(GetDisconnects()->Empty()); 1775 EXPECT_TRUE(GetMisconnects()->Empty()); 1776} 1777 1778TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) { 1779 const int kNow = 5; 1780 EXPECT_FALSE(service_->explicitly_disconnected()); 1781 SetStateField(Service::kStateOnline); 1782 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, ""))); 1783 NoteDisconnectEvent(); 1784 ASSERT_EQ(1, GetDisconnects()->Size()); 1785 EXPECT_EQ(kNow, GetDisconnects()->Front().monotonic.tv_sec); 1786 EXPECT_TRUE(GetMisconnects()->Empty()); 1787 1788 Mock::VerifyAndClearExpectations(&time_); 1789 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp( 1790 kNow + GetDisconnectsMonitorSeconds() - 1, 1791 kNow + GetDisconnectsMonitorSeconds() - 1, 1792 ""))); 1793 EXPECT_TRUE(service_->HasRecentConnectionIssues()); 1794 ASSERT_EQ(1, GetDisconnects()->Size()); 1795 1796 Mock::VerifyAndClearExpectations(&time_); 1797 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp( 1798 kNow + GetDisconnectsMonitorSeconds(), 1799 kNow + GetDisconnectsMonitorSeconds(), 1800 ""))); 1801 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1802 ASSERT_TRUE(GetDisconnects()->Empty()); 1803} 1804 1805TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) { 1806 const int kNow = 7; 1807 EXPECT_FALSE(service_->explicitly_disconnected()); 1808 SetStateField(Service::kStateConfiguring); 1809 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, ""))); 1810 NoteDisconnectEvent(); 1811 EXPECT_TRUE(GetDisconnects()->Empty()); 1812 ASSERT_EQ(1, GetMisconnects()->Size()); 1813 EXPECT_EQ(kNow, GetMisconnects()->Front().monotonic.tv_sec); 1814 1815 Mock::VerifyAndClearExpectations(&time_); 1816 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp( 1817 kNow + GetMisconnectsMonitorSeconds() - 1, 1818 kNow + GetMisconnectsMonitorSeconds() - 1, 1819 ""))); 1820 EXPECT_TRUE(service_->HasRecentConnectionIssues()); 1821 ASSERT_EQ(1, GetMisconnects()->Size()); 1822 1823 Mock::VerifyAndClearExpectations(&time_); 1824 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp( 1825 kNow + GetMisconnectsMonitorSeconds(), 1826 kNow + GetMisconnectsMonitorSeconds(), 1827 ""))); 1828 EXPECT_FALSE(service_->HasRecentConnectionIssues()); 1829 ASSERT_TRUE(GetMisconnects()->Empty()); 1830} 1831 1832TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) { 1833 EXPECT_FALSE(service_->explicitly_disconnected()); 1834 for (int i = 0; i < 2; i++) { 1835 int now = 0; 1836 EventHistory* events = nullptr; 1837 if (i == 0) { 1838 SetStateField(Service::kStateConnected); 1839 now = GetDisconnectsMonitorSeconds() + 1; 1840 events = GetDisconnects(); 1841 } else { 1842 SetStateField(Service::kStateAssociating); 1843 now = GetMisconnectsMonitorSeconds() + 1; 1844 events = GetMisconnects(); 1845 } 1846 PushTimestamp(events, 0, 0, ""); 1847 PushTimestamp(events, 0, 0, ""); 1848 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, now, ""))); 1849 NoteDisconnectEvent(); 1850 ASSERT_EQ(1, events->Size()); 1851 EXPECT_EQ(now, events->Front().monotonic.tv_sec); 1852 } 1853} 1854 1855TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) { 1856 EXPECT_FALSE(service_->explicitly_disconnected()); 1857 SetStateField(Service::kStateOnline); 1858 for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) { 1859 PushTimestamp(GetDisconnects(), 0, 0, ""); 1860 } 1861 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp())); 1862 NoteDisconnectEvent(); 1863 EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->Size()); 1864} 1865 1866TEST_F(ServiceTest, NoteMisconnectEventDiscardExcessive) { 1867 EXPECT_FALSE(service_->explicitly_disconnected()); 1868 SetStateField(Service::kStateAssociating); 1869 for (int i = 0; i < 2 * GetMaxMisconnectEventHistory(); i++) { 1870 PushTimestamp(GetMisconnects(), 0, 0, ""); 1871 } 1872 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp())); 1873 NoteDisconnectEvent(); 1874 EXPECT_EQ(GetMaxMisconnectEventHistory(), GetMisconnects()->Size()); 1875} 1876 1877TEST_F(ServiceTest, DiagnosticsProperties) { 1878 const string kWallClock0 = "2012-12-09T12:41:22.234567-0800"; 1879 const string kWallClock1 = "2012-12-31T23:59:59.345678-0800"; 1880 Strings values; 1881 1882 PushTimestamp(GetDisconnects(), 0, 0, kWallClock0); 1883 Error unused_error; 1884 ASSERT_TRUE(service_->store().GetStringsProperty( 1885 kDiagnosticsDisconnectsProperty, &values, &unused_error)); 1886 ASSERT_EQ(1, values.size()); 1887 EXPECT_EQ(kWallClock0, values[0]); 1888 1889 PushTimestamp(GetMisconnects(), 0, 0, kWallClock1); 1890 ASSERT_TRUE(service_->store().GetStringsProperty( 1891 kDiagnosticsMisconnectsProperty, &values, &unused_error)); 1892 ASSERT_EQ(1, values.size()); 1893 EXPECT_EQ(kWallClock1, values[0]); 1894} 1895 1896TEST_F(ServiceTest, SecurityLevel) { 1897 // Encrypted is better than not. 1898 service_->SetSecurity(Service::kCryptoNone, false, false); 1899 service2_->SetSecurity(Service::kCryptoRc4, false, false); 1900 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1901 1902 // AES encryption is better than RC4 encryption. 1903 service_->SetSecurity(Service::kCryptoRc4, false, false); 1904 service2_->SetSecurity(Service::kCryptoAes, false, false); 1905 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1906 1907 // Crypto algorithm is more important than key rotation. 1908 service_->SetSecurity(Service::kCryptoNone, true, false); 1909 service2_->SetSecurity(Service::kCryptoAes, false, false); 1910 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1911 1912 // Encrypted-but-unauthenticated is better than clear-but-authenticated. 1913 service_->SetSecurity(Service::kCryptoNone, false, true); 1914 service2_->SetSecurity(Service::kCryptoAes, false, false); 1915 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1916 1917 // For same encryption, prefer key rotation. 1918 service_->SetSecurity(Service::kCryptoRc4, false, false); 1919 service2_->SetSecurity(Service::kCryptoRc4, true, false); 1920 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1921 1922 // For same encryption, prefer authenticated AP. 1923 service_->SetSecurity(Service::kCryptoRc4, false, false); 1924 service2_->SetSecurity(Service::kCryptoRc4, false, true); 1925 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel()); 1926} 1927 1928TEST_F(ServiceTest, SetErrorDetails) { 1929 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details()); 1930 static const char kDetails[] = "Certificate revoked."; 1931 ServiceMockAdaptor* adaptor = GetAdaptor(); 1932 EXPECT_CALL(*adaptor, EmitStringChanged(kErrorDetailsProperty, kDetails)); 1933 service_->SetErrorDetails(Service::kErrorDetailsNone); 1934 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details()); 1935 service_->SetErrorDetails(kDetails); 1936 EXPECT_EQ(kDetails, service_->error_details()); 1937 service_->SetErrorDetails(kDetails); 1938} 1939 1940TEST_F(ServiceTest, SetAutoConnectFull) { 1941 EXPECT_FALSE(service_->auto_connect()); 1942 Error error; 1943 EXPECT_FALSE(GetAutoConnect(&error)); 1944 EXPECT_TRUE(error.IsSuccess()); 1945 1946 // false -> false 1947 EXPECT_FALSE(service_->retain_auto_connect()); 1948 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 1949 SetAutoConnectFull(false, &error); 1950 EXPECT_TRUE(error.IsSuccess()); 1951 EXPECT_FALSE(service_->auto_connect()); 1952 EXPECT_TRUE(service_->retain_auto_connect()); 1953 EXPECT_FALSE(GetAutoConnect(nullptr)); 1954 Mock::VerifyAndClearExpectations(&mock_manager_); 1955 1956 // Clear the |retain_auto_connect_| flag for the next test. 1957 service_->Unload(); 1958 ASSERT_FALSE(service_->retain_auto_connect()); 1959 1960 // false -> true 1961 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1); 1962 SetAutoConnectFull(true, &error); 1963 EXPECT_TRUE(error.IsSuccess()); 1964 EXPECT_TRUE(service_->auto_connect()); 1965 EXPECT_TRUE(GetAutoConnect(nullptr)); 1966 EXPECT_TRUE(service_->retain_auto_connect()); 1967 Mock::VerifyAndClearExpectations(&mock_manager_); 1968 1969 // Clear the |retain_auto_connect_| flag for the next test. 1970 service_->Unload(); 1971 ASSERT_FALSE(service_->retain_auto_connect()); 1972 1973 // true -> true 1974 service_->SetAutoConnect(true); 1975 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 1976 SetAutoConnectFull(true, &error); 1977 EXPECT_TRUE(error.IsSuccess()); 1978 EXPECT_TRUE(service_->auto_connect()); 1979 EXPECT_TRUE(GetAutoConnect(nullptr)); 1980 EXPECT_TRUE(service_->retain_auto_connect()); 1981 Mock::VerifyAndClearExpectations(&mock_manager_); 1982 1983 // Clear the |retain_auto_connect_| flag for the next test. 1984 service_->Unload(); 1985 ASSERT_FALSE(service_->retain_auto_connect()); 1986 1987 // true -> false 1988 service_->SetAutoConnect(true); 1989 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1); 1990 SetAutoConnectFull(false, &error); 1991 EXPECT_TRUE(error.IsSuccess()); 1992 EXPECT_FALSE(service_->auto_connect()); 1993 EXPECT_FALSE(GetAutoConnect(nullptr)); 1994 EXPECT_TRUE(service_->retain_auto_connect()); 1995 Mock::VerifyAndClearExpectations(&mock_manager_); 1996} 1997 1998TEST_F(ServiceTest, SetAutoConnectFullUserUpdatePersists) { 1999 // If the user sets the kAutoConnectProperty explicitly, the preference must 2000 // be persisted, even if the property was not changed. 2001 Error error; 2002 MockProfileRefPtr mock_profile( 2003 new MockProfile(control_interface(), metrics(), &mock_manager_)); 2004 NiceMock<MockStore> storage; 2005 service_->set_profile(mock_profile); 2006 service_->SetAutoConnect(true); 2007 2008 EXPECT_CALL(*mock_profile, UpdateService(_)); 2009 EXPECT_CALL(*mock_profile, GetConstStorage()) 2010 .WillOnce(Return(&storage)); 2011 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_))) 2012 .WillOnce(Return(false)); 2013 EXPECT_FALSE(service_->retain_auto_connect()); 2014 SetAutoConnectFull(true, &error); 2015 EXPECT_TRUE(error.IsSuccess()); 2016 EXPECT_TRUE(service_->auto_connect()); 2017 EXPECT_TRUE(service_->retain_auto_connect()); 2018} 2019 2020TEST_F(ServiceTest, ClearAutoConnect) { 2021 EXPECT_FALSE(service_->auto_connect()); 2022 Error error; 2023 EXPECT_FALSE(GetAutoConnect(&error)); 2024 EXPECT_TRUE(error.IsSuccess()); 2025 2026 // unset -> false 2027 EXPECT_FALSE(service_->retain_auto_connect()); 2028 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 2029 ClearAutoConnect(&error); 2030 EXPECT_TRUE(error.IsSuccess()); 2031 EXPECT_FALSE(service_->retain_auto_connect()); 2032 EXPECT_FALSE(GetAutoConnect(nullptr)); 2033 Mock::VerifyAndClearExpectations(&mock_manager_); 2034 2035 // false -> false 2036 SetAutoConnectFull(false, &error); 2037 EXPECT_FALSE(GetAutoConnect(nullptr)); 2038 EXPECT_TRUE(service_->retain_auto_connect()); 2039 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 2040 ClearAutoConnect(&error); 2041 EXPECT_TRUE(error.IsSuccess()); 2042 EXPECT_FALSE(service_->retain_auto_connect()); 2043 EXPECT_FALSE(GetAutoConnect(nullptr)); 2044 Mock::VerifyAndClearExpectations(&mock_manager_); 2045 2046 // true -> false 2047 SetAutoConnectFull(true, &error); 2048 EXPECT_TRUE(error.IsSuccess()); 2049 EXPECT_TRUE(GetAutoConnect(nullptr)); 2050 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1); 2051 ClearAutoConnect(&error); 2052 EXPECT_FALSE(service_->retain_auto_connect()); 2053 EXPECT_FALSE(GetAutoConnect(nullptr)); 2054 Mock::VerifyAndClearExpectations(&mock_manager_); 2055} 2056 2057TEST_F(ServiceTest, UniqueAttributes) { 2058 EXPECT_NE(service_->serial_number_, service2_->serial_number_); 2059 EXPECT_NE(service_->unique_name(), service2_->unique_name()); 2060} 2061 2062TEST_F(ServiceTest, PropertyChanges) { 2063 TestCommonPropertyChanges(service_, GetAdaptor()); 2064 TestAutoConnectPropertyChange(service_, GetAdaptor()); 2065} 2066 2067// Custom property setters should return false, and make no changes, if 2068// the new value is the same as the old value. 2069TEST_F(ServiceTest, CustomSetterNoopChange) { 2070 TestCustomSetterNoopChange(service_, &mock_manager_); 2071} 2072 2073TEST_F(ServiceTest, GetTethering) { 2074 Error error; 2075 EXPECT_EQ("", service_->GetTethering(&error)); 2076 EXPECT_EQ(Error::kNotSupported, error.type()); 2077} 2078 2079class ServiceWithMockOnPropertyChanged : public ServiceUnderTest { 2080 public: 2081 ServiceWithMockOnPropertyChanged(ControlInterface* control_interface, 2082 EventDispatcher* dispatcher, 2083 Metrics* metrics, 2084 Manager* manager) 2085 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {} 2086 MOCK_METHOD1(OnPropertyChanged, void(const string& property)); 2087}; 2088 2089TEST_F(ServiceTest, ConfigureServiceTriggersOnPropertyChanged) { 2090 auto service(make_scoped_refptr( 2091 new ServiceWithMockOnPropertyChanged(control_interface(), 2092 dispatcher(), 2093 metrics(), 2094 &mock_manager_))); 2095 KeyValueStore args; 2096 args.SetString(kUIDataProperty, "terpsichorean ejectamenta"); 2097 args.SetBool(kSaveCredentialsProperty, false); 2098 2099 // Calling Configure with different values from before triggers a single 2100 // OnPropertyChanged call per property. 2101 EXPECT_CALL(*service, OnPropertyChanged(kUIDataProperty)).Times(1); 2102 EXPECT_CALL(*service, OnPropertyChanged(kSaveCredentialsProperty)).Times(1); 2103 { 2104 Error error; 2105 service->Configure(args, &error); 2106 EXPECT_TRUE(error.IsSuccess()); 2107 } 2108 Mock::VerifyAndClearExpectations(service.get()); 2109 2110 // Calling Configure with the same values as before should not trigger 2111 // OnPropertyChanged(). 2112 EXPECT_CALL(*service, OnPropertyChanged(_)).Times(0); 2113 { 2114 Error error; 2115 service->Configure(args, &error); 2116 EXPECT_TRUE(error.IsSuccess()); 2117 } 2118} 2119 2120TEST_F(ServiceTest, ClearExplicitlyDisconnected) { 2121 EXPECT_FALSE(GetExplicitlyDisconnected()); 2122 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0); 2123 service_->ClearExplicitlyDisconnected(); 2124 Mock::VerifyAndClearExpectations(&mock_manager_); 2125 2126 SetExplicitlyDisconnected(true); 2127 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_))); 2128 service_->ClearExplicitlyDisconnected(); 2129 Mock::VerifyAndClearExpectations(&mock_manager_); 2130 EXPECT_FALSE(GetExplicitlyDisconnected()); 2131} 2132 2133TEST_F(ServiceTest, Compare) { 2134 // Construct our Services so that the string comparison of 2135 // unique_name_ differs from the numerical comparison of 2136 // serial_number_. 2137 vector<scoped_refptr<MockService>> mock_services; 2138 for (size_t i = 0; i < 11; ++i) { 2139 mock_services.push_back( 2140 new NiceMock<MockService>(control_interface(), 2141 dispatcher(), 2142 metrics(), 2143 manager())); 2144 } 2145 scoped_refptr<MockService> service2 = mock_services[2]; 2146 scoped_refptr<MockService> service10 = mock_services[10]; 2147 mock_services.clear(); 2148 2149 // Services should already be sorted by |serial_number_|. 2150 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2151 2152 // Two otherwise equal services should be reordered by strength 2153 service10->SetStrength(1); 2154 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2155 2156 scoped_refptr<MockProfile> profile2( 2157 new MockProfile(control_interface(), metrics(), manager(), "")); 2158 scoped_refptr<MockProfile> profile10( 2159 new MockProfile(control_interface(), metrics(), manager(), "")); 2160 2161 service2->set_profile(profile2); 2162 service10->set_profile(profile10); 2163 2164 // When comparing two services with different profiles, prefer the one 2165 // that is not ephemeral. 2166 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service2))) 2167 .WillRepeatedly(Return(false)); 2168 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service10))) 2169 .WillRepeatedly(Return(true)); 2170 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2171 Mock::VerifyAndClearExpectations(&mock_manager_); 2172 2173 // Prefer the service with the more recently applied profile if neither 2174 // service is ephemeral. 2175 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)) 2176 .WillRepeatedly(Return(false)); 2177 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile2), 2178 IsRefPtrTo(profile10))) 2179 .WillRepeatedly(Return(true)); 2180 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile10), 2181 IsRefPtrTo(profile2))) 2182 .WillRepeatedly(Return(false)); 2183 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2184 2185 // Security. 2186 service2->SetSecurity(Service::kCryptoAes, true, true); 2187 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2188 2189 // PriorityWithinTechnology. 2190 service10->SetPriorityWithinTechnology(1, nullptr); 2191 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2192 service2->SetPriorityWithinTechnology(2, nullptr); 2193 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2194 2195 // Technology. 2196 EXPECT_CALL(*service2.get(), technology()) 2197 .WillRepeatedly(Return((Technology::kWifi))); 2198 EXPECT_CALL(*service10.get(), technology()) 2199 .WillRepeatedly(Return(Technology::kEthernet)); 2200 2201 technology_order_for_sorting_ = {Technology::kEthernet, Technology::kWifi}; 2202 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2203 2204 technology_order_for_sorting_ = {Technology::kWifi, Technology::kEthernet}; 2205 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2206 2207 // Priority. 2208 service2->SetPriority(1, nullptr); 2209 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2210 service10->SetPriority(2, nullptr); 2211 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2212 2213 // A service that has been connected before should be considered 2214 // above a service that neither been connected to before nor has 2215 // has managed credentials. 2216 service2->has_ever_connected_ = true; 2217 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2218 2219 // If one service has been connected to before, and the other is managed 2220 // by Chrome they should rank same, so the priority will be considered 2221 // instead. 2222 service10->managed_credentials_ = true; 2223 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2224 service2->SetPriority(3, nullptr); 2225 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2226 2227 // A service with managed credentials should be considered above one that 2228 // has neither been connected to before nor has managed credentials. 2229 service2->has_ever_connected_ = false; 2230 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2231 2232 // Auto-connect. 2233 service2->SetAutoConnect(true); 2234 service10->SetAutoConnect(false); 2235 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2236 2237 // Test is-dependent-on. 2238 EXPECT_CALL(*service10.get(), 2239 IsDependentOn(IsRefPtrTo(service2.get()))) 2240 .WillOnce(Return(true)) 2241 .WillOnce(Return(false)); 2242 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2243 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2244 2245 // It doesn't make sense to have is-dependent-on ranking comparison in any of 2246 // the remaining subtests below. Reset to the default. 2247 EXPECT_CALL(*service10.get(), IsDependentOn(_)).WillRepeatedly(Return(false)); 2248 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2249 2250 // Connectable. 2251 service10->SetConnectable(true); 2252 service2->SetConnectable(false); 2253 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2254 2255 // IsFailed. 2256 EXPECT_CALL(*service2.get(), state()) 2257 .WillRepeatedly(Return(Service::kStateIdle)); 2258 EXPECT_CALL(*service2.get(), IsFailed()) 2259 .WillRepeatedly(Return(false)); 2260 EXPECT_CALL(*service10.get(), state()) 2261 .WillRepeatedly(Return(Service::kStateFailure)); 2262 EXPECT_CALL(*service10.get(), IsFailed()) 2263 .WillRepeatedly(Return(true)); 2264 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2265 2266 // Connecting. 2267 EXPECT_CALL(*service10.get(), state()) 2268 .WillRepeatedly(Return(Service::kStateAssociating)); 2269 EXPECT_CALL(*service10.get(), IsConnecting()) 2270 .WillRepeatedly(Return(true)); 2271 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2272 2273 // Connected-but-portalled preferred over unconnected. 2274 EXPECT_CALL(*service2.get(), state()) 2275 .WillRepeatedly(Return(Service::kStatePortal)); 2276 EXPECT_CALL(*service2.get(), IsConnected()) 2277 .WillRepeatedly(Return(true)); 2278 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10)); 2279 2280 // Connected preferred over connected-but-portalled. 2281 service10->SetConnectable(false); 2282 service2->SetConnectable(true); 2283 EXPECT_CALL(*service10.get(), state()) 2284 .WillRepeatedly(Return(Service::kStateConnected)); 2285 EXPECT_CALL(*service10.get(), IsConnected()) 2286 .WillRepeatedly(Return(true)); 2287 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2288 2289 // Online preferred over just connected. 2290 EXPECT_CALL(*service2.get(), state()) 2291 .WillRepeatedly(Return(Service::kStateOnline)); 2292 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2)); 2293 2294 // Connectivity state ignored if this is specified. 2295 const bool kDoNotCompareConnectivityState = false; 2296 EXPECT_TRUE(SortingOrderIs(service2, service10, 2297 kDoNotCompareConnectivityState)); 2298} 2299 2300} // namespace shill 2301