// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "shill/service.h"

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/bind.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus-c++/dbus.h>
#include <gtest/gtest.h>
#include <gmock/gmock.h>

#include "shill/dbus_adaptor.h"
#include "shill/ethernet_service.h"
#include "shill/event_dispatcher.h"
#include "shill/manager.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_diagnostics_reporter.h"
#include "shill/mock_eap_credentials.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_power_manager.h"
#include "shill/mock_profile.h"
#include "shill/mock_proxy_factory.h"
#include "shill/mock_store.h"
#include "shill/mock_time.h"
#include "shill/property_store_unittest.h"
#include "shill/service_property_change_test.h"
#include "shill/service_under_test.h"
#include "shill/testing.h"

using base::Bind;
using base::Unretained;
using std::deque;
using std::map;
using std::string;
using std::vector;
using testing::_;
using testing::AnyNumber;
using testing::AtLeast;
using testing::DefaultValue;
using testing::DoAll;
using testing::HasSubstr;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::ReturnNull;
using testing::ReturnRef;
using testing::StrictMock;
using testing::SetArgumentPointee;
using testing::Test;
using testing::Values;

namespace shill {

class ServiceTest : public PropertyStoreTest {
 public:
  ServiceTest()
      : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
        service_(new ServiceUnderTest(control_interface(),
                                      dispatcher(),
                                      metrics(),
                                      &mock_manager_)),
        service2_(new ServiceUnderTest(control_interface(),
                                       dispatcher(),
                                       metrics(),
                                       &mock_manager_)),
        storage_id_(ServiceUnderTest::kStorageId),
        power_manager_(new MockPowerManager(nullptr, &proxy_factory_)),
        eap_(new MockEapCredentials()) {
    ON_CALL(proxy_factory_, CreatePowerManagerProxy(_))
        .WillByDefault(ReturnNull());

    service_->time_ = &time_;
    DefaultValue<Timestamp>::Set(Timestamp());
    service_->diagnostics_reporter_ = &diagnostics_reporter_;
    service_->eap_.reset(eap_);  // Passes ownership.
    mock_manager_.running_ = true;
    mock_manager_.set_power_manager(power_manager_);  // Passes ownership.
  }

  virtual ~ServiceTest() {}

  MOCK_METHOD1(TestCallback, void(const Error &error));

 protected:
  typedef scoped_refptr<MockProfile> MockProfileRefPtr;

  ServiceMockAdaptor *GetAdaptor() {
    return dynamic_cast<ServiceMockAdaptor *>(service_->adaptor());
  }

  string GetFriendlyName() { return service_->friendly_name(); }

  void SetManagerRunning(bool running) { mock_manager_.running_ = running; }

  void SetSuspending(bool suspending) {
    power_manager_->suspending_ = suspending;
  }

  bool GetExplicitlyDisconnected() const {
    return service_->explicitly_disconnected_;
  }

  void SetExplicitlyDisconnected(bool explicitly) {
    service_->explicitly_disconnected_ = explicitly;
  }

  void SetStateField(Service::ConnectState state) { service_->state_ = state; }

  Service::ConnectState GetPreviousState() const {
    return service_->previous_state_;
  }

  void NoteDisconnectEvent() {
    service_->NoteDisconnectEvent();
  }

  deque<Timestamp> *GetDisconnects() {
    return &service_->disconnects_;
  }
  deque<Timestamp> *GetMisconnects() {
    return &service_->misconnects_;
  }

  Timestamp GetTimestamp(int monotonic_seconds, int boottime_seconds,
                         const string &wall_clock) {
    struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 };
    struct timeval boottime = { .tv_sec = boottime_seconds, .tv_usec = 0 };
    return Timestamp(monotonic, boottime, wall_clock);
  }

  void PushTimestamp(deque<Timestamp> *timestamps,
                     int monotonic_seconds,
                     int boottime_seconds,
                     const string &wall_clock) {
    timestamps->push_back(
        GetTimestamp(monotonic_seconds, boottime_seconds, wall_clock));
  }

  int GetDisconnectsMonitorSeconds() {
    return Service::kDisconnectsMonitorSeconds;
  }

  int GetMisconnectsMonitorSeconds() {
    return Service::kMisconnectsMonitorSeconds;
  }

  int GetReportDisconnectsThreshold() {
    return Service::kReportDisconnectsThreshold;
  }

  int GetReportMisconnectsThreshold() {
    return Service::kReportMisconnectsThreshold;
  }

  int GetMaxDisconnectEventHistory() {
    return Service::kMaxDisconnectEventHistory;
  }

  static Strings ExtractWallClockToStrings(const deque<Timestamp> &timestamps) {
    return Service::ExtractWallClockToStrings(timestamps);
  }

  bool GetAutoConnect(Error *error) {
    return service_->GetAutoConnect(error);
  }

  void ClearAutoConnect(Error *error) {
    service_->ClearAutoConnect(error);
  }

  bool SetAutoConnectFull(bool connect, Error *error) {
    return service_->SetAutoConnectFull(connect, error);
  }

  MockManager mock_manager_;
  MockDiagnosticsReporter diagnostics_reporter_;
  MockTime time_;
  scoped_refptr<ServiceUnderTest> service_;
  scoped_refptr<ServiceUnderTest> service2_;
  string storage_id_;
  NiceMock<MockProxyFactory> proxy_factory_;
  MockPowerManager *power_manager_;  // Owned by |mock_manager_|.
  MockEapCredentials *eap_;  // Owned by |service_|.
};

class AllMockServiceTest : public testing::Test {
 public:
  AllMockServiceTest()
      : metrics_(&dispatcher_),
        manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
        service_(new ServiceUnderTest(&control_interface_,
                                      &dispatcher_,
                                      &metrics_,
                                      &manager_)) { }
  virtual ~AllMockServiceTest() {}

 protected:
  MockControl control_interface_;
  StrictMock<MockEventDispatcher> dispatcher_;
  MockGLib glib_;
  NiceMock<MockMetrics> metrics_;
  MockManager manager_;
  scoped_refptr<ServiceUnderTest> service_;
};

TEST_F(ServiceTest, Constructor) {
  EXPECT_TRUE(service_->save_credentials_);
  EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
  EXPECT_EQ(Service::kStateIdle, service_->state());
  EXPECT_FALSE(service_->has_ever_connected());
  EXPECT_EQ(0, service_->previous_error_serial_number_);
  EXPECT_EQ("", service_->previous_error_);
}

TEST_F(ServiceTest, CalculateState) {
  service_->state_ = Service::kStateConnected;
  Error error;
  EXPECT_EQ(kStateReady, service_->CalculateState(&error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ServiceTest, CalculateTechnology) {
  service_->technology_ = Technology::kWifi;
  Error error;
  EXPECT_EQ(kTypeWifi, service_->CalculateTechnology(&error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ServiceTest, GetProperties) {
  map<string, ::DBus::Variant> props;
  Error error(Error::kInvalidProperty, "");
  {
    ::DBus::Error dbus_error;
    string expected("true");
    service_->mutable_store()->SetStringProperty(kCheckPortalProperty,
                                                 expected,
                                                 &error);
    DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
    ASSERT_FALSE(props.find(kCheckPortalProperty) == props.end());
    EXPECT_EQ(props[kCheckPortalProperty].reader().get_string(),
              expected);
  }
  {
    ::DBus::Error dbus_error;
    bool expected = true;
    service_->mutable_store()->SetBoolProperty(kAutoConnectProperty,
                                               expected,
                                               &error);
    DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
    ASSERT_FALSE(props.find(kAutoConnectProperty) == props.end());
    EXPECT_EQ(props[kAutoConnectProperty].reader().get_bool(),
              expected);
  }
  {
    ::DBus::Error dbus_error;
    DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
    ASSERT_FALSE(props.find(kConnectableProperty) == props.end());
    EXPECT_EQ(props[kConnectableProperty].reader().get_bool(), false);
  }
  {
    ::DBus::Error dbus_error;
    int32_t expected = 127;
    service_->mutable_store()->SetInt32Property(kPriorityProperty,
                                                expected,
                                                &error);
    DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
    ASSERT_FALSE(props.find(kPriorityProperty) == props.end());
    EXPECT_EQ(props[kPriorityProperty].reader().get_int32(),
              expected);
  }
  {
    ::DBus::Error dbus_error;
    DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
    ASSERT_FALSE(props.find(kDeviceProperty) == props.end());
    EXPECT_EQ(props[kDeviceProperty].reader().get_path(),
              string(ServiceUnderTest::kRpcId));
  }
}

TEST_F(ServiceTest, SetProperty) {
  {
    ::DBus::Error error;
    EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                         kSaveCredentialsProperty,
                                         PropertyStoreTest::kBoolV,
                                         &error));
  }
  {
    ::DBus::Error error;
    ::DBus::Variant priority;
    priority.writer().append_int32(1);
    EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                         kPriorityProperty,
                                         priority,
                                         &error));
  }
  {
    ::DBus::Error error;
    ::DBus::Variant guid;
    guid.writer().append_string("not default");
    EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                         kGuidProperty,
                                         guid,
                                         &error));
  }
  // Ensure that EAP properties cannot be set on services with no EAP
  // credentials.  Use service2_ here since we're have some code in
  // ServiceTest::SetUp() that fiddles with service_->eap_.
  {
    ::DBus::Error error;
    ::DBus::Variant eap;
    eap.writer().append_string("eap eep eip!");
    EXPECT_FALSE(DBusAdaptor::SetProperty(service2_->mutable_store(),
                                          kEapMethodProperty,
                                          eap,
                                          &error));
    ASSERT_TRUE(error.is_set());  // name() may be invalid otherwise
    EXPECT_EQ(invalid_prop(), error.name());
    // Now plumb in eap credentials, and try again.
    service2_->SetEapCredentials(new EapCredentials());
    EXPECT_TRUE(DBusAdaptor::SetProperty(service2_->mutable_store(),
                                         kEapMethodProperty,
                                         eap,
                                         &error));
  }
  // Ensure that an attempt to write a R/O property returns InvalidArgs error.
  {
    ::DBus::Error error;
    EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                          kConnectableProperty,
                                          PropertyStoreTest::kBoolV,
                                          &error));
    ASSERT_TRUE(error.is_set());  // name() may be invalid otherwise
    EXPECT_EQ(invalid_args(), error.name());
  }
  {
    ::DBus::Error error;
    ::DBus::Variant auto_connect;
    auto_connect.writer().append_bool(true);
    EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                         kAutoConnectProperty,
                                         auto_connect,
                                         &error));
  }
  // Ensure that we can perform a trivial set of the Name property (to its
  // current value) but an attempt to set the property to a different value
  // fails.
  {
    ::DBus::Error error;
    EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                          kNameProperty,
                                          DBusAdaptor::StringToVariant(
                                              GetFriendlyName()),
                                          &error));
    EXPECT_FALSE(error.is_set());
  }
  {
    ::DBus::Error error;
    EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
                                          kNameProperty,
                                          PropertyStoreTest::kStringV,
                                          &error));
    ASSERT_TRUE(error.is_set());  // name() may be invalid otherwise
    EXPECT_EQ(invalid_args(), error.name());
  }
}

TEST_F(ServiceTest, GetLoadableStorageIdentifier) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_))
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage));
  EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage));
}

TEST_F(ServiceTest, IsLoadableFrom) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_))
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  EXPECT_FALSE(service_->IsLoadableFrom(storage));
  EXPECT_TRUE(service_->IsLoadableFrom(storage));
}

class ServiceWithOnEapCredentialsChangedOverride : public ServiceUnderTest {
 public:
  ServiceWithOnEapCredentialsChangedOverride(
      ControlInterface *control_interface,
      EventDispatcher *dispatcher,
      Metrics *metrics,
      Manager *manager,
      EapCredentials *eap)
      : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {
    SetEapCredentials(eap);
  }
  void OnEapCredentialsChanged(Service::UpdateCredentialsReason) override {
    SetHasEverConnected(false);
  }
};

TEST_F(ServiceTest, Load) {
  MockEapCredentials *eap = new MockEapCredentials();  // Owned by |service|.
  scoped_refptr<ServiceWithOnEapCredentialsChangedOverride> service(
      new ServiceWithOnEapCredentialsChangedOverride(control_interface(),
                                                     dispatcher(),
                                                     metrics(),
                                                     &mock_manager_,
                                                     eap));

  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
  const string kCheckPortal("check-portal");
  const string kGUID("guid");
  const bool kHasEverConnected = true;
  const int kPriority = 20;
  const string kProxyConfig("proxy-config");
  const string kUIData("ui-data");
  EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true)));
  EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true)));
  EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true)));
  EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true)));
  EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true)));
  EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(storage,
              GetBool(storage_id_, Service::kStorageSaveCredentials, _));
  EXPECT_CALL(storage,
              GetBool(storage_id_, Service::kStorageHasEverConnected, _))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
                            Return(true)));
  EXPECT_CALL(*eap, Load(&storage, storage_id_));
  EXPECT_TRUE(service->Load(&storage));

  EXPECT_EQ(kCheckPortal, service->check_portal_);
  EXPECT_EQ(kGUID, service->guid_);
  EXPECT_TRUE(service->has_ever_connected_);
  EXPECT_EQ(kProxyConfig, service->proxy_config_);
  EXPECT_EQ(kUIData, service->ui_data_);

  Mock::VerifyAndClearExpectations(&storage);
  Mock::VerifyAndClearExpectations(eap_);

  // Assure that parameters are set to default if not available in the profile.
  EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
  EXPECT_CALL(storage, GetBool(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(storage, GetString(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(storage, GetInt(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*eap, Load(&storage, storage_id_));
  EXPECT_TRUE(service->Load(&storage));

  EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
  EXPECT_EQ("", service->guid_);
  EXPECT_EQ("", service->proxy_config_);
  EXPECT_EQ("", service->ui_data_);
  EXPECT_FALSE(service->has_ever_connected_);
}

TEST_F(ServiceTest, LoadFail) {
  StrictMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
  EXPECT_FALSE(service_->Load(&storage));
}

TEST_F(ServiceTest, LoadAutoConnect) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, GetBool(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(storage, GetString(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(storage, GetInt(storage_id_, _, _))
      .WillRepeatedly(Return(false));
  EXPECT_CALL(*eap_, Load(&storage, storage_id_)).Times(AnyNumber());

  // Three of each expectation so we can test Favorite == unset, false, true.
  EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageAutoConnect, _))
      .WillOnce(Return(false))
      .WillOnce(Return(false))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
  EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageFavorite, _))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));

  // AutoConnect is unset, Favorite is unset.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_FALSE(service_->retain_auto_connect());

  // AutoConnect is unset, Favorite is false.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_FALSE(service_->retain_auto_connect());

  // AutoConnect is unset, Favorite is true.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());

  // AutoConnect is false, Favorite is unset.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());

  // AutoConnect is false, Favorite is false.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_FALSE(service_->retain_auto_connect());

  // AutoConnect is false, Favorite is true.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());

  // AutoConnect is true, Favorite is unset.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());

  // AutoConnect is true, Favorite is false (invalid case).
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_FALSE(service_->retain_auto_connect());

  // AutoConnect is true, Favorite is true.
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());
}

TEST_F(ServiceTest, SaveString) {
  MockStore storage;
  static const char kKey[] = "test-key";
  static const char kData[] = "test-data";
  EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
      .WillOnce(Return(true));
  service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
}

TEST_F(ServiceTest, SaveStringCrypted) {
  MockStore storage;
  static const char kKey[] = "test-key";
  static const char kData[] = "test-data";
  EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
      .WillOnce(Return(true));
  service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
}

TEST_F(ServiceTest, SaveStringDontSave) {
  MockStore storage;
  static const char kKey[] = "test-key";
  EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
      .WillOnce(Return(true));
  service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
}

TEST_F(ServiceTest, SaveStringEmpty) {
  MockStore storage;
  static const char kKey[] = "test-key";
  EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
      .WillOnce(Return(true));
  service_->SaveString(&storage, storage_id_, kKey, "", true, true);
}

TEST_F(ServiceTest, Save) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, SetString(storage_id_, _, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
      .WillOnce(Return(true));
  EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(storage,
              SetBool(storage_id_,
                      Service::kStorageSaveCredentials,
                      service_->save_credentials()));
  EXPECT_CALL(*eap_, Save(&storage, storage_id_, true));
  EXPECT_TRUE(service_->Save(&storage));
}

TEST_F(ServiceTest, RetainAutoConnect) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, SetString(storage_id_, _, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
      .Times(2);
  EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
      .Times(0);
  EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);

  // AutoConnect flag set true.
  service_->EnableAndRetainAutoConnect();
  EXPECT_CALL(storage,
              SetBool(storage_id_, Service::kStorageAutoConnect, true));
  EXPECT_TRUE(service_->Save(&storage));

  // AutoConnect flag set false.
  EXPECT_CALL(storage,
              SetBool(storage_id_, Service::kStorageAutoConnect, false));
  service_->SetAutoConnect(false);
  EXPECT_TRUE(service_->Save(&storage));
}

TEST_F(ServiceTest, HasEverConnectedSavedToProfile) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, SetString(storage_id_, _, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage, DeleteKey(storage_id_, _))
      .Times(AtLeast(1))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(storage,
              DeleteKey(storage_id_, Service::kStorageHasEverConnected))
      .Times(0);
  EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
  EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);

  // HasEverConnected flag set true.
  service_->SetHasEverConnected(true);
  EXPECT_CALL(storage,
              SetBool(storage_id_, Service::kStorageHasEverConnected, true));
  EXPECT_TRUE(service_->Save(&storage));

  // HasEverConnected flag set false.
  EXPECT_CALL(storage,
              SetBool(storage_id_, Service::kStorageHasEverConnected, false));
  service_->SetHasEverConnected(false);
  EXPECT_TRUE(service_->Save(&storage));
}

TEST_F(ServiceTest, Unload) {
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
  static const string string_value("value");
  EXPECT_CALL(storage, GetString(storage_id_, _, _))
      .Times(AtLeast(1))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
  EXPECT_CALL(storage, GetBool(storage_id_, _, _))
      .Times(AtLeast(1))
      .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
  EXPECT_FALSE(service_->explicitly_disconnected_);
  service_->explicitly_disconnected_ = true;
  EXPECT_FALSE(service_->has_ever_connected_);
  EXPECT_CALL(*eap_, Load(&storage, storage_id_));
  ASSERT_TRUE(service_->Load(&storage));
  // TODO(pstew): Only two string properties in the service are tested as
  // a sentinel that properties are being set and reset at the right times.
  // However, since property load/store is essentially a manual process,
  // it is error prone and should either be exhaustively unit-tested or
  // a generic framework for registering loaded/stored properties should
  // be created. crbug.com/207798
  EXPECT_EQ(string_value, service_->ui_data_);
  EXPECT_EQ(string_value, service_->guid_);
  EXPECT_FALSE(service_->explicitly_disconnected_);
  EXPECT_TRUE(service_->has_ever_connected_);
  service_->explicitly_disconnected_ = true;
  EXPECT_CALL(*eap_, Reset());
  service_->Unload();
  EXPECT_EQ(string(""), service_->ui_data_);
  EXPECT_EQ(string(""), service_->guid_);
  EXPECT_FALSE(service_->explicitly_disconnected_);
  EXPECT_FALSE(service_->has_ever_connected_);
}

TEST_F(ServiceTest, State) {
  EXPECT_EQ(Service::kStateIdle, service_->state());
  EXPECT_EQ(Service::kStateIdle, GetPreviousState());
  EXPECT_EQ(Service::kFailureUnknown, service_->failure());
  const string unknown_error(
      Service::ConnectFailureToString(Service::kFailureUnknown));
  EXPECT_EQ(unknown_error, service_->error());

  EXPECT_CALL(*GetAdaptor(),
              EmitStringChanged(kStateProperty, _)).Times(6);
  EXPECT_CALL(*GetAdaptor(),
              EmitStringChanged(kErrorProperty, _)).Times(4);
  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  service_->SetState(Service::kStateConnected);
  EXPECT_EQ(Service::kStateIdle, GetPreviousState());
  // A second state change shouldn't cause another update
  service_->SetState(Service::kStateConnected);
  EXPECT_EQ(Service::kStateConnected, service_->state());
  EXPECT_EQ(Service::kStateIdle, GetPreviousState());
  EXPECT_EQ(Service::kFailureUnknown, service_->failure());
  EXPECT_TRUE(service_->has_ever_connected_);

  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  service_->SetFailure(Service::kFailureOutOfRange);
  EXPECT_TRUE(service_->IsFailed());
  EXPECT_GT(service_->failed_time_, 0);
  EXPECT_GT(service_->previous_error_serial_number_, 0);
  EXPECT_EQ(Service::kStateFailure, service_->state());
  EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
  const string out_of_range_error(
      Service::ConnectFailureToString(Service::kFailureOutOfRange));
  EXPECT_EQ(out_of_range_error, service_->error());
  EXPECT_EQ(out_of_range_error, service_->previous_error_);

  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  service_->SetState(Service::kStateConnected);
  EXPECT_FALSE(service_->IsFailed());
  EXPECT_EQ(service_->failed_time_, 0);
  EXPECT_EQ(unknown_error, service_->error());
  EXPECT_EQ(out_of_range_error, service_->previous_error_);
  EXPECT_GT(service_->previous_error_serial_number_, 0);

  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  service_->SetFailureSilent(Service::kFailurePinMissing);
  EXPECT_TRUE(service_->IsFailed());
  EXPECT_GT(service_->failed_time_, 0);
  EXPECT_GT(service_->previous_error_serial_number_, 0);
  EXPECT_EQ(Service::kStateIdle, service_->state());
  EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
  const string pin_missing_error(
      Service::ConnectFailureToString(Service::kFailurePinMissing));
  EXPECT_EQ(pin_missing_error, service_->error());
  EXPECT_EQ(pin_missing_error, service_->previous_error_);

  // If the Service has a Profile, the profile should be saved when
  // the service enters kStateConnected. (The case where the service
  // doesn't have a profile is tested above.)
  MockProfileRefPtr mock_profile(
      new MockProfile(control_interface(), metrics(), &mock_manager_));
  NiceMock<MockStore> storage;
  service_->set_profile(mock_profile);
  service_->has_ever_connected_ = false;
  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  EXPECT_CALL(*mock_profile, GetConstStorage())
      .WillOnce(Return(&storage));
  EXPECT_CALL(*mock_profile, UpdateService(IsRefPtrTo(service_)));
  service_->SetState(Service::kStateConnected);
  EXPECT_TRUE(service_->has_ever_connected_);
  service_->set_profile(nullptr);  // Break reference cycle.

  // Similar to the above, but emulate an emphemeral profile, which
  // has no storage. We can't update the service in the profile, but
  // we should not crash.
  service_->state_ = Service::kStateIdle;  // Skips state change logic.
  service_->set_profile(mock_profile);
  service_->has_ever_connected_ = false;
  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  EXPECT_CALL(*mock_profile, GetConstStorage()).WillOnce(Return(nullptr));
  service_->SetState(Service::kStateConnected);
  EXPECT_TRUE(service_->has_ever_connected_);
  service_->set_profile(nullptr);  // Break reference cycle.
}

TEST_F(ServiceTest, PortalDetectionFailure) {
  EXPECT_CALL(*GetAdaptor(),
              EmitStringChanged(kPortalDetectionFailedPhaseProperty,
                                kPortalDetectionPhaseDns)).Times(1);
  EXPECT_CALL(*GetAdaptor(),
              EmitStringChanged(kPortalDetectionFailedStatusProperty,
                                kPortalDetectionStatusTimeout)).Times(1);
  service_->SetPortalDetectionFailure(kPortalDetectionPhaseDns,
                                      kPortalDetectionStatusTimeout);
  EXPECT_EQ(kPortalDetectionPhaseDns,
            service_->portal_detection_failure_phase_);
  EXPECT_EQ(kPortalDetectionStatusTimeout,
            service_->portal_detection_failure_status_);
}

TEST_F(ServiceTest, StateResetAfterFailure) {
  service_->SetFailure(Service::kFailureOutOfRange);
  EXPECT_EQ(Service::kStateFailure, service_->state());
  Error error;
  service_->Connect(&error, "in test");
  EXPECT_EQ(Service::kStateIdle, service_->state());
  EXPECT_EQ(Service::kFailureUnknown, service_->failure());

  service_->SetState(Service::kStateConnected);
  service_->Connect(&error, "in test");
  EXPECT_EQ(Service::kStateConnected, service_->state());
}

TEST_F(ServiceTest, UserInitiatedConnectionResult) {
  service_->technology_ = Technology::kWifi;
  Error error;
  // User-initiated connection attempt succeed.
  service_->SetState(Service::kStateIdle);
  service_->UserInitiatedConnect(&error);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
      Metrics::kMetricWifiUserInitiatedConnectionResult,
      Metrics::kUserInitiatedConnectionResultSuccess));
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
      .Times(0);
  service_->SetState(Service::kStateConnected);
  Mock::VerifyAndClearExpectations(metrics());

  // User-initiated connection attempt failed.
  service_->SetState(Service::kStateIdle);
  service_->UserInitiatedConnect(&error);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
      Metrics::kMetricWifiUserInitiatedConnectionResult,
      Metrics::kUserInitiatedConnectionResultFailure));
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(
      Metrics::kMetricWifiUserInitiatedConnectionFailureReason,
      Service::kFailureDHCP));
  service_->SetFailure(Service::kFailureDHCP);
  Mock::VerifyAndClearExpectations(metrics());

  // User-initiated connection attempt aborted.
  service_->SetState(Service::kStateIdle);
  service_->UserInitiatedConnect(&error);
  service_->SetState(Service::kStateAssociating);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
      Metrics::kMetricWifiUserInitiatedConnectionResult,
      Metrics::kUserInitiatedConnectionResultAborted));
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
      .Times(0);
  service_->SetState(Service::kStateIdle);
  Mock::VerifyAndClearExpectations(metrics());

  // No metric reporting for other state transition.
  service_->SetState(Service::kStateIdle);
  service_->UserInitiatedConnect(&error);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
      .Times(0);
  service_->SetState(Service::kStateAssociating);
  service_->SetState(Service::kStateConfiguring);
  Mock::VerifyAndClearExpectations(metrics());

  // No metric reporting for non-user-initiated connection.
  service_->SetState(Service::kStateIdle);
  service_->Connect(&error, "in test");
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
      .Times(0);
  service_->SetState(Service::kStateConnected);
  Mock::VerifyAndClearExpectations(metrics());

  // No metric reporting for other technology.
  service_->technology_ = Technology::kCellular;
  service_->SetState(Service::kStateIdle);
  service_->UserInitiatedConnect(&error);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
  EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
      .Times(0);
  service_->SetFailure(Service::kFailureDHCP);
  Mock::VerifyAndClearExpectations(metrics());
}

TEST_F(ServiceTest, ActivateCellularModem) {
  ResultCallback callback =
      Bind(&ServiceTest::TestCallback, Unretained(this));
  EXPECT_CALL(*this, TestCallback(_)).Times(0);
  Error error;
  service_->ActivateCellularModem("Carrier", &error, callback);
  EXPECT_TRUE(error.IsFailure());
}

TEST_F(ServiceTest, CompleteCellularActivation) {
  Error error;
  service_->CompleteCellularActivation(&error);
  EXPECT_EQ(Error::kNotSupported, error.type());
}

TEST_F(ServiceTest, EnableAndRetainAutoConnect) {
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_FALSE(service_->auto_connect());

  service_->EnableAndRetainAutoConnect();
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_TRUE(service_->auto_connect());
}

TEST_F(ServiceTest, ReRetainAutoConnect) {
  service_->EnableAndRetainAutoConnect();
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_TRUE(service_->auto_connect());

  service_->SetAutoConnect(false);
  service_->EnableAndRetainAutoConnect();
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_FALSE(service_->auto_connect());
}

TEST_F(ServiceTest, IsAutoConnectable) {
  const char *reason = nullptr;
  service_->SetConnectable(true);

  // Services with non-primary connectivity technologies should not auto-connect
  // when the system is offline.
  EXPECT_EQ(Technology::kUnknown, service_->technology());
  EXPECT_CALL(mock_manager_, IsConnected()).WillOnce(Return(false));
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnOffline, reason);

  service_->technology_ = Technology::kEthernet;
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // We should not auto-connect to a Service that a user has
  // deliberately disconnected.
  Error error;
  service_->UserInitiatedDisconnect(&error);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);

  // But if the Service is reloaded, it is eligible for auto-connect
  // again.
  NiceMock<MockStore> storage;
  EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
  EXPECT_CALL(*eap_, Load(&storage, storage_id_));
  EXPECT_TRUE(service_->Load(&storage));
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // A deliberate Connect should also re-enable auto-connect.
  service_->UserInitiatedDisconnect(&error);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  service_->Connect(&error, "in test");
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // A non-user initiated Disconnect doesn't change anything.
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // A resume also re-enables auto-connect.
  service_->UserInitiatedDisconnect(&error);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  service_->OnAfterResume();
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  service_->SetState(Service::kStateConnected);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnConnected, reason);

  service_->SetState(Service::kStateAssociating);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnConnecting, reason);

  service_->SetState(Service::kStateIdle);
  EXPECT_CALL(mock_manager_, IsTechnologyAutoConnectDisabled(
                                 service_->technology_)).WillOnce(Return(true));
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnTechnologyNotConnectable, reason);
}

TEST_F(ServiceTest, AutoConnectLogging) {
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _));
  service_->SetConnectable(true);

  ScopeLogger::GetInstance()->EnableScopesByName("+service");
  ScopeLogger::GetInstance()->set_verbose_level(1);
  service_->SetState(Service::kStateConnected);
  EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected)));
  service_->AutoConnect();

  ScopeLogger::GetInstance()->EnableScopesByName("-service");
  ScopeLogger::GetInstance()->set_verbose_level(0);
  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
                       HasSubstr(Service::kAutoConnNotConnectable)));
  service_->SetConnectable(false);
  service_->AutoConnect();
}


TEST_F(AllMockServiceTest, AutoConnectWithFailures) {
  const char *reason;
  service_->SetConnectable(true);
  service_->technology_ = Technology::kEthernet;
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // The very first AutoConnect() doesn't trigger any throttling.
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
  service_->AutoConnect();
  Mock::VerifyAndClearExpectations(&dispatcher_);
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // The second call does trigger some throttling.
  EXPECT_CALL(dispatcher_, PostDelayedTask(_,
      Service::kMinAutoConnectCooldownTimeMilliseconds));
  service_->AutoConnect();
  Mock::VerifyAndClearExpectations(&dispatcher_);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnThrottled, reason);

  // Calling AutoConnect() again before the cooldown terminates does not change
  // the timeout.
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
  service_->AutoConnect();
  Mock::VerifyAndClearExpectations(&dispatcher_);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnThrottled, reason);

  // Once the timeout expires, we can AutoConnect() again.
  service_->ReEnableAutoConnectTask();
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));

  // Timeouts increase exponentially.
  uint64_t next_cooldown_time = service_->auto_connect_cooldown_milliseconds_;
  EXPECT_EQ(next_cooldown_time,
            Service::kAutoConnectCooldownBackoffFactor *
            Service::kMinAutoConnectCooldownTimeMilliseconds);
  while (next_cooldown_time <=
         Service::kMaxAutoConnectCooldownTimeMilliseconds) {
    EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time));
    service_->AutoConnect();
    Mock::VerifyAndClearExpectations(&dispatcher_);
    EXPECT_FALSE(service_->IsAutoConnectable(&reason));
    EXPECT_STREQ(Service::kAutoConnThrottled, reason);
    service_->ReEnableAutoConnectTask();
    next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor;
  }

  // Once we hit our cap, future timeouts are the same.
  for (int32_t i = 0; i < 2; i++) {
    EXPECT_CALL(dispatcher_, PostDelayedTask(_,
        Service::kMaxAutoConnectCooldownTimeMilliseconds));
    service_->AutoConnect();
    Mock::VerifyAndClearExpectations(&dispatcher_);
    EXPECT_FALSE(service_->IsAutoConnectable(&reason));
    EXPECT_STREQ(Service::kAutoConnThrottled, reason);
    service_->ReEnableAutoConnectTask();
  }

  // Connecting successfully resets our cooldown.
  service_->SetState(Service::kStateConnected);
  service_->SetState(Service::kStateIdle);
  reason = "";
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ("", reason);
  EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0);

  // But future AutoConnects behave as before
  EXPECT_CALL(dispatcher_, PostDelayedTask(_,
      Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1);
  service_->AutoConnect();
  service_->AutoConnect();
  Mock::VerifyAndClearExpectations(&dispatcher_);
  EXPECT_FALSE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ(Service::kAutoConnThrottled, reason);

  // Cooldowns are forgotten if we go through a suspend/resume cycle.
  service_->OnAfterResume();
  reason = "";
  EXPECT_TRUE(service_->IsAutoConnectable(&reason));
  EXPECT_STREQ("", reason);
}

TEST_F(ServiceTest, ConfigureBadProperty) {
  KeyValueStore args;
  args.SetString("XXXInvalid", "Value");
  Error error;
  service_->Configure(args, &error);
  EXPECT_FALSE(error.IsSuccess());
}

TEST_F(ServiceTest, ConfigureBoolProperty) {
  service_->EnableAndRetainAutoConnect();
  service_->SetAutoConnect(false);
  ASSERT_FALSE(service_->auto_connect());
  KeyValueStore args;
  args.SetBool(kAutoConnectProperty, true);
  Error error;
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service_->auto_connect());
}

TEST_F(ServiceTest, ConfigureStringProperty) {
  const string kGuid0 = "guid_zero";
  const string kGuid1 = "guid_one";
  service_->SetGuid(kGuid0, nullptr);
  ASSERT_EQ(kGuid0, service_->guid());
  KeyValueStore args;
  args.SetString(kGuidProperty, kGuid1);
  Error error;
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kGuid1, service_->guid());
}

TEST_F(ServiceTest, ConfigureStringsProperty) {
  const vector<string> kStrings0{ "string0", "string1" };
  const vector<string> kStrings1{ "string2", "string3" };
  service_->set_strings(kStrings0);
  ASSERT_EQ(kStrings0, service_->strings());
  KeyValueStore args;
  args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
  Error error;
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kStrings1, service_->strings());
}

TEST_F(ServiceTest, ConfigureEapStringProperty) {
  MockEapCredentials *eap = new MockEapCredentials();
  service2_->SetEapCredentials(eap);  // Passes ownership.

  const string kEAPManagement0 = "management_zero";
  const string kEAPManagement1 = "management_one";
  service2_->SetEAPKeyManagement(kEAPManagement0);

  EXPECT_CALL(*eap, key_management())
      .WillOnce(ReturnRef(kEAPManagement0));
  ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement());
  KeyValueStore args;
  EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _));
  args.SetString(kEapKeyMgmtProperty, kEAPManagement1);
  Error error;
  service2_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ServiceTest, ConfigureIntProperty) {
  const int kPriority0 = 100;
  const int kPriority1 = 200;
  service_->SetPriority(kPriority0, nullptr);
  ASSERT_EQ(kPriority0, service_->priority());
  KeyValueStore args;
  args.SetInt(kPriorityProperty, kPriority1);
  Error error;
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kPriority1, service_->priority());
}

TEST_F(ServiceTest, ConfigureIgnoredProperty) {
  service_->EnableAndRetainAutoConnect();
  service_->SetAutoConnect(false);
  ASSERT_FALSE(service_->auto_connect());
  KeyValueStore args;
  args.SetBool(kAutoConnectProperty, true);
  Error error;
  service_->IgnoreParameterForConfigure(kAutoConnectProperty);
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->auto_connect());
}

TEST_F(ServiceTest, ConfigureProfileProperty) {
  // Ensure that the Profile property is always ignored.
  KeyValueStore args;
  args.SetString(kProfileProperty, "profile");
  Error error;
  EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
  service_->Configure(args, &error);
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(ServiceTest, DoPropertiesMatch) {
  service_->SetAutoConnect(false);
  const string kGUID0 = "guid_zero";
  const string kGUID1 = "guid_one";
  service_->SetGuid(kGUID0, nullptr);
  const uint32_t kPriority0 = 100;
  const uint32_t kPriority1 = 200;
  service_->SetPriority(kPriority0, nullptr);
  const vector<string> kStrings0{ "string0", "string1" };
  const vector<string> kStrings1{ "string2", "string3" };
  service_->set_strings(kStrings0);

  {
    KeyValueStore args;
    args.SetString(kGuidProperty, kGUID0);
    args.SetBool(kAutoConnectProperty, false);
    args.SetInt(kPriorityProperty, kPriority0);
    args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
    EXPECT_TRUE(service_->DoPropertiesMatch(args));
  }
  {
    KeyValueStore args;
    args.SetString(kGuidProperty, kGUID1);
    args.SetBool(kAutoConnectProperty, false);
    args.SetInt(kPriorityProperty, kPriority0);
    args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
    EXPECT_FALSE(service_->DoPropertiesMatch(args));
  }
  {
    KeyValueStore args;
    args.SetString(kGuidProperty, kGUID0);
    args.SetBool(kAutoConnectProperty, true);
    args.SetInt(kPriorityProperty, kPriority0);
    args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
    EXPECT_FALSE(service_->DoPropertiesMatch(args));
  }
  {
    KeyValueStore args;
    args.SetString(kGuidProperty, kGUID0);
    args.SetBool(kAutoConnectProperty, false);
    args.SetInt(kPriorityProperty, kPriority1);
    args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
    EXPECT_FALSE(service_->DoPropertiesMatch(args));
  }
  {
    KeyValueStore args;
    args.SetString(kGuidProperty, kGUID0);
    args.SetBool(kAutoConnectProperty, false);
    args.SetInt(kPriorityProperty, kPriority0);
    args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
    EXPECT_FALSE(service_->DoPropertiesMatch(args));
  }
}

TEST_F(ServiceTest, IsRemembered) {
  service_->set_profile(nullptr);
  EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
  EXPECT_FALSE(service_->IsRemembered());

  scoped_refptr<MockProfile> profile(
      new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
  service_->set_profile(profile);
  EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
     .WillOnce(Return(true))
     .WillOnce(Return(false));
  EXPECT_FALSE(service_->IsRemembered());
  EXPECT_TRUE(service_->IsRemembered());
}

TEST_F(ServiceTest, IsDependentOn) {
  EXPECT_FALSE(service_->IsDependentOn(nullptr));

  std::unique_ptr<MockDeviceInfo> mock_device_info(
      new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
                                   &mock_manager_));
  scoped_refptr<MockConnection> mock_connection0(
      new NiceMock<MockConnection>(mock_device_info.get()));
  scoped_refptr<MockConnection> mock_connection1(
      new NiceMock<MockConnection>(mock_device_info.get()));

  service_->connection_ = mock_connection0;
  EXPECT_CALL(*mock_connection0, GetLowerConnection())
      .WillRepeatedly(Return(mock_connection1));
  EXPECT_CALL(*mock_connection1, GetLowerConnection())
      .WillRepeatedly(Return(ConnectionRefPtr()));
  EXPECT_FALSE(service_->IsDependentOn(nullptr));

  scoped_refptr<ServiceUnderTest> service1 =
      new ServiceUnderTest(control_interface(),
                           dispatcher(),
                           metrics(),
                           &mock_manager_);
  EXPECT_FALSE(service_->IsDependentOn(service1));

  service1->connection_ = mock_connection0;
  EXPECT_FALSE(service_->IsDependentOn(service1));

  service1->connection_ = mock_connection1;
  EXPECT_TRUE(service_->IsDependentOn(service1));

  service_->connection_ = mock_connection1;
  service1->connection_ = nullptr;
  EXPECT_FALSE(service_->IsDependentOn(service1));

  service_->connection_ = nullptr;
}

TEST_F(ServiceTest, OnPropertyChanged) {
  scoped_refptr<MockProfile> profile(
      new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
  service_->set_profile(nullptr);
  // Expect no crash.
  service_->OnPropertyChanged("");

  // Expect no call to Update if the profile has no storage.
  service_->set_profile(profile);
  EXPECT_CALL(*profile, UpdateService(_)).Times(0);
  EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(nullptr));
  service_->OnPropertyChanged("");

  // Expect call to Update if the profile has storage.
  EXPECT_CALL(*profile, UpdateService(_)).Times(1);
  NiceMock<MockStore> storage;
  EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
  service_->OnPropertyChanged("");
}


TEST_F(ServiceTest, RecheckPortal) {
  service_->state_ = Service::kStateIdle;
  EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
  service_->OnPropertyChanged(kCheckPortalProperty);

  service_->state_ = Service::kStatePortal;
  EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
      .Times(1);
  service_->OnPropertyChanged(kCheckPortalProperty);

  service_->state_ = Service::kStateConnected;
  EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
      .Times(1);
  service_->OnPropertyChanged(kProxyConfigProperty);

  service_->state_ = Service::kStateOnline;
  EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
      .Times(1);
  service_->OnPropertyChanged(kCheckPortalProperty);

  service_->state_ = Service::kStatePortal;
  EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
  service_->OnPropertyChanged(kEapKeyIdProperty);
}

TEST_F(ServiceTest, SetCheckPortal) {
  {
    Error error;
    service_->SetCheckPortal("false", &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
  }
  {
    Error error;
    service_->SetCheckPortal("true", &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
  }
  {
    Error error;
    service_->SetCheckPortal("auto", &error);
    EXPECT_TRUE(error.IsSuccess());
    EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
  }
  {
    Error error;
    service_->SetCheckPortal("xxx", &error);
    EXPECT_FALSE(error.IsSuccess());
    EXPECT_EQ(Error::kInvalidArguments, error.type());
    EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
  }
}

TEST_F(ServiceTest, SetFriendlyName) {
  EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
  ServiceMockAdaptor *adaptor = GetAdaptor();

  EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
  service_->SetFriendlyName(service_->unique_name_);
  EXPECT_EQ(service_->unique_name_, service_->friendly_name_);

  EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
                                          "Test Name 1"));
  service_->SetFriendlyName("Test Name 1");
  EXPECT_EQ("Test Name 1", service_->friendly_name_);

  EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
  service_->SetFriendlyName("Test Name 1");
  EXPECT_EQ("Test Name 1", service_->friendly_name_);

  EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
                                          "Test Name 2"));
  service_->SetFriendlyName("Test Name 2");
  EXPECT_EQ("Test Name 2", service_->friendly_name_);
}

TEST_F(ServiceTest, SetConnectableFull) {
  EXPECT_FALSE(service_->connectable());

  ServiceMockAdaptor *adaptor = GetAdaptor();

  EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0);
  EXPECT_CALL(mock_manager_, HasService(_)).Times(0);
  service_->SetConnectableFull(false);
  EXPECT_FALSE(service_->connectable());

  EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
  EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false));
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  service_->SetConnectableFull(true);
  EXPECT_TRUE(service_->connectable());

  EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, false));
  EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
  EXPECT_CALL(mock_manager_, UpdateService(_));
  service_->SetConnectableFull(false);
  EXPECT_FALSE(service_->connectable());

  EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
  EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
              EXPECT_CALL(mock_manager_, UpdateService(_));
  service_->SetConnectableFull(true);
  EXPECT_TRUE(service_->connectable());
}

class WriteOnlyServicePropertyTest : public ServiceTest {};
TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) {
  // Use a real EapCredentials instance since the base Service class
  // contains no write-only properties.
  EapCredentials eap;
  eap.InitPropertyStore(service_->mutable_store());

  string property(GetParam().reader().get_string());
  Error error;
  EXPECT_FALSE(service_->store().GetStringProperty(property, nullptr, &error));
  EXPECT_EQ(Error::kPermissionDenied, error.type());
}

INSTANTIATE_TEST_CASE_P(
    WriteOnlyServicePropertyTestInstance,
    WriteOnlyServicePropertyTest,
    Values(
        DBusAdaptor::StringToVariant(kEapPrivateKeyPasswordProperty),
        DBusAdaptor::StringToVariant(kEapPasswordProperty)));


TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
  {
    Error error;
    EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
    EXPECT_EQ(Error::kNotFound, error.type());
  }

  std::unique_ptr<MockDeviceInfo> mock_device_info(
      new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
                                   &mock_manager_));
  scoped_refptr<MockConnection> mock_connection(
      new NiceMock<MockConnection>(mock_device_info.get()));

  service_->connection_ = mock_connection;

  {
    Error error;
    const string empty_string;
    EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
        .WillOnce(ReturnRef(empty_string));
    EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
    EXPECT_EQ(Error::kNotFound, error.type());
  }

  {
    Error error;
    const string nonempty_string("/ipconfig/path");
    EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
        .WillOnce(ReturnRef(nonempty_string));
    EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
    EXPECT_EQ(Error::kSuccess, error.type());
  }

  // Assure orderly destruction of the Connection before DeviceInfo.
  service_->connection_ = nullptr;
  mock_connection = nullptr;
  mock_device_info.reset();
}

class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest {
 public:
  ServiceWithMockOnEapCredentialsChanged(ControlInterface *control_interface,
                                         EventDispatcher *dispatcher,
                                         Metrics *metrics,
                                         Manager *manager)
      : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
        is_8021x_(false) {}
  MOCK_METHOD1(OnEapCredentialsChanged, void(Service::UpdateCredentialsReason));
  virtual bool Is8021x() const { return is_8021x_; }
  void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }

 private:
  bool is_8021x_;
};

TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
  scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service(
      new ServiceWithMockOnEapCredentialsChanged(control_interface(),
                                                 dispatcher(),
                                                 metrics(),
                                                 &mock_manager_));
  string eap_credential_properties[] = {
      kEapAnonymousIdentityProperty,
      kEapCertIdProperty,
      kEapClientCertProperty,
      kEapIdentityProperty,
      kEapKeyIdProperty,
      kEapPasswordProperty,
      kEapPinProperty,
      kEapPrivateKeyProperty,
      kEapPrivateKeyPasswordProperty
  };
  string eap_non_credential_properties[] = {
      kEapCaCertIdProperty,
      kEapCaCertNssProperty,
      kEapMethodProperty,
      kEapPhase2AuthProperty,
      kEapUseSystemCasProperty
  };
  // While this is not an 802.1x-based service, none of these property
  // changes should cause a call to set_eap().
  EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
  for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
    service->OnPropertyChanged(eap_credential_properties[i]);
  for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
    service->OnPropertyChanged(eap_non_credential_properties[i]);
  service->OnPropertyChanged(kEapKeyMgmtProperty);

  service->set_is_8021x(true);

  // When this is an 802.1x-based service, set_eap should be called for
  // all credential-carrying properties.
  for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
    EXPECT_CALL(*service,
                OnEapCredentialsChanged(
                    Service::kReasonPropertyUpdate)).Times(1);
    service->OnPropertyChanged(eap_credential_properties[i]);
    Mock::VerifyAndClearExpectations(service.get());
  }

  // The key management property is a special case.  While not strictly
  // a credential, it can change which credentials are used.  Therefore it
  // should also trigger a call to set_eap();
  EXPECT_CALL(*service,
              OnEapCredentialsChanged(Service::kReasonPropertyUpdate)).Times(1);
  service->OnPropertyChanged(kEapKeyMgmtProperty);
  Mock::VerifyAndClearExpectations(service.get());

  EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
  for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
    service->OnPropertyChanged(eap_non_credential_properties[i]);
}

TEST_F(ServiceTest, Certification) {
  EXPECT_FALSE(service_->remote_certification_.size());

  ScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
                       HasSubstr("exceeds our maximum"))).Times(2);
  string kSubject("foo");
  EXPECT_FALSE(service_->AddEAPCertification(
      kSubject, Service::kEAPMaxCertificationElements));
  EXPECT_FALSE(service_->AddEAPCertification(
      kSubject, Service::kEAPMaxCertificationElements + 1));
  EXPECT_FALSE(service_->remote_certification_.size());
  Mock::VerifyAndClearExpectations(&log);

  EXPECT_CALL(log,
              Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
      .Times(1);
  EXPECT_TRUE(service_->AddEAPCertification(
      kSubject, Service::kEAPMaxCertificationElements - 1));
  Mock::VerifyAndClearExpectations(&log);
  EXPECT_EQ(Service::kEAPMaxCertificationElements,
      service_->remote_certification_.size());
  for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) {
      EXPECT_TRUE(service_->remote_certification_[i].empty());
  }
  EXPECT_EQ(kSubject, service_->remote_certification_[
      Service::kEAPMaxCertificationElements - 1]);

  // Re-adding the same name in the same position should not generate a log.
  EXPECT_CALL(log, Log(_, _, _)).Times(0);
  EXPECT_TRUE(service_->AddEAPCertification(
      kSubject, Service::kEAPMaxCertificationElements - 1));

  // Replacing the item should generate a log message.
  EXPECT_CALL(log,
              Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
      .Times(1);
  EXPECT_TRUE(service_->AddEAPCertification(
      kSubject + "x", Service::kEAPMaxCertificationElements - 1));

  service_->ClearEAPCertification();
  EXPECT_TRUE(service_->remote_certification_.empty());
}

TEST_F(ServiceTest, NoteDisconnectEventIdle) {
  Timestamp timestamp;
  EXPECT_CALL(time_, GetNow()).Times(4).WillRepeatedly((Return(timestamp)));
  SetStateField(Service::kStateOnline);
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  service_->SetState(Service::kStateIdle);
  // The transition Online->Idle is not an event.
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  service_->SetState(Service::kStateFailure);
  // The transition Online->Idle->Failure is a connection drop.
  EXPECT_TRUE(service_->HasRecentConnectionIssues());
}

TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) {
  Timestamp timestamp;
  EXPECT_CALL(time_, GetNow()).Times(3).WillRepeatedly((Return(timestamp)));
  SetStateField(Service::kStateOnline);
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  service_->SetState(Service::kStateFailure);
  EXPECT_TRUE(service_->HasRecentConnectionIssues());
}

TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) {
  Timestamp timestamp;
  EXPECT_CALL(time_, GetNow()).Times(3).WillRepeatedly((Return(timestamp)));
  SetStateField(Service::kStateConfiguring);
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  service_->SetFailureSilent(Service::kFailureEAPAuthentication);
  EXPECT_TRUE(service_->HasRecentConnectionIssues());
}

TEST_F(ServiceTest, NoteDisconnectEventNonEvent) {
  EXPECT_CALL(time_, GetNow()).Times(0);
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);

  // Explicit disconnect is a non-event.
  SetStateField(Service::kStateOnline);
  SetExplicitlyDisconnected(true);
  NoteDisconnectEvent();
  EXPECT_TRUE(GetDisconnects()->empty());
  EXPECT_TRUE(GetMisconnects()->empty());

  // Failure to idle transition is a non-event.
  SetStateField(Service::kStateFailure);
  SetExplicitlyDisconnected(false);
  NoteDisconnectEvent();
  EXPECT_TRUE(GetDisconnects()->empty());
  EXPECT_TRUE(GetMisconnects()->empty());

  // Disconnect while manager is stopped is a non-event.
  SetStateField(Service::kStateOnline);
  SetManagerRunning(false);
  NoteDisconnectEvent();
  EXPECT_TRUE(GetDisconnects()->empty());
  EXPECT_TRUE(GetMisconnects()->empty());

  // Disconnect while suspending is a non-event.
  SetManagerRunning(true);
  SetSuspending(true);
  NoteDisconnectEvent();
  EXPECT_TRUE(GetDisconnects()->empty());
  EXPECT_TRUE(GetMisconnects()->empty());
}

TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) {
  const int kNow = 5;
  EXPECT_FALSE(service_->explicitly_disconnected());
  SetStateField(Service::kStateOnline);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
  NoteDisconnectEvent();
  ASSERT_EQ(1, GetDisconnects()->size());
  EXPECT_EQ(kNow, GetDisconnects()->front().monotonic.tv_sec);
  EXPECT_TRUE(GetMisconnects()->empty());

  Mock::VerifyAndClearExpectations(&time_);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
      kNow + GetDisconnectsMonitorSeconds() - 1,
      kNow + GetDisconnectsMonitorSeconds() - 1,
      "")));
  EXPECT_TRUE(service_->HasRecentConnectionIssues());
  ASSERT_EQ(1, GetDisconnects()->size());

  Mock::VerifyAndClearExpectations(&time_);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
      kNow + GetDisconnectsMonitorSeconds(),
      kNow + GetDisconnectsMonitorSeconds(),
      "")));
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  ASSERT_TRUE(GetDisconnects()->empty());
}

TEST_F(ServiceTest, NoteDisconnectEventDisconnectThreshold) {
  EXPECT_FALSE(service_->explicitly_disconnected());
  SetStateField(Service::kStateOnline);
  const int kNow = 6;
  for (int i = 0; i < GetReportDisconnectsThreshold() - 1; i++) {
    PushTimestamp(GetDisconnects(), kNow, kNow, "");
  }
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
  NoteDisconnectEvent();
  EXPECT_EQ(GetReportDisconnectsThreshold(), GetDisconnects()->size());
}

TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) {
  const int kNow = 7;
  EXPECT_FALSE(service_->explicitly_disconnected());
  SetStateField(Service::kStateConfiguring);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
  NoteDisconnectEvent();
  EXPECT_TRUE(GetDisconnects()->empty());
  ASSERT_EQ(1, GetMisconnects()->size());
  EXPECT_EQ(kNow, GetMisconnects()->front().monotonic.tv_sec);

  Mock::VerifyAndClearExpectations(&time_);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
      kNow + GetMisconnectsMonitorSeconds() - 1,
      kNow + GetMisconnectsMonitorSeconds() - 1,
      "")));
  EXPECT_TRUE(service_->HasRecentConnectionIssues());
  ASSERT_EQ(1, GetMisconnects()->size());

  Mock::VerifyAndClearExpectations(&time_);
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
      kNow + GetMisconnectsMonitorSeconds(),
      kNow + GetMisconnectsMonitorSeconds(),
      "")));
  EXPECT_FALSE(service_->HasRecentConnectionIssues());
  ASSERT_TRUE(GetMisconnects()->empty());
}

TEST_F(ServiceTest, NoteDisconnectEventMisconnectThreshold) {
  EXPECT_FALSE(service_->explicitly_disconnected());
  SetStateField(Service::kStateConfiguring);
  const int kNow = 8;
  for (int i = 0; i < GetReportMisconnectsThreshold() - 1; i++) {
    PushTimestamp(GetMisconnects(), kNow, kNow, "");
  }
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
  NoteDisconnectEvent();
  EXPECT_EQ(GetReportMisconnectsThreshold(), GetMisconnects()->size());
}

TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) {
  EXPECT_FALSE(service_->explicitly_disconnected());
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
  for (int i = 0; i < 2; i++) {
    int now = 0;
    deque<Timestamp> *events = nullptr;
    if (i == 0) {
      SetStateField(Service::kStateConnected);
      now = GetDisconnectsMonitorSeconds() + 1;
      events = GetDisconnects();
    } else {
      SetStateField(Service::kStateAssociating);
      now = GetMisconnectsMonitorSeconds() + 1;
      events = GetMisconnects();
    }
    PushTimestamp(events, 0, 0, "");
    PushTimestamp(events, 0, 0, "");
    EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, now, "")));
    NoteDisconnectEvent();
    ASSERT_EQ(1, events->size());
    EXPECT_EQ(now, events->front().monotonic.tv_sec);
  }
}

TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) {
  EXPECT_FALSE(service_->explicitly_disconnected());
  SetStateField(Service::kStateOnline);
  for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) {
    PushTimestamp(GetDisconnects(), 0, 0, "");
  }
  EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
  EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
  NoteDisconnectEvent();
  EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->size());
}

TEST_F(ServiceTest, ConvertTimestampsToStrings) {
  EXPECT_TRUE(ExtractWallClockToStrings(deque<Timestamp>()).empty());

  const Timestamp kValues[] = {
    GetTimestamp(123, 123, "2012-12-09T12:41:22.123456+0100"),
    GetTimestamp(234, 234, "2012-12-31T23:59:59.012345+0100")
  };
  Strings strings =
      ExtractWallClockToStrings(
          deque<Timestamp>(kValues, kValues + arraysize(kValues)));
  EXPECT_GT(arraysize(kValues), 0);
  ASSERT_EQ(arraysize(kValues), strings.size());
  for (size_t i = 0; i < arraysize(kValues); i++) {
    EXPECT_EQ(kValues[i].wall_clock, strings[i]);
  }
}

TEST_F(ServiceTest, DiagnosticsProperties) {
  const string kWallClock0 = "2012-12-09T12:41:22.234567-0800";
  const string kWallClock1 = "2012-12-31T23:59:59.345678-0800";
  Strings values;

  PushTimestamp(GetDisconnects(), 0, 0, kWallClock0);
  Error unused_error;
  ASSERT_TRUE(service_->store().GetStringsProperty(
     kDiagnosticsDisconnectsProperty, &values, &unused_error));
  ASSERT_EQ(1, values.size());
  EXPECT_EQ(kWallClock0, values[0]);

  PushTimestamp(GetMisconnects(), 0, 0, kWallClock1);
  ASSERT_TRUE(service_->store().GetStringsProperty(
      kDiagnosticsMisconnectsProperty, &values, &unused_error));
  ASSERT_EQ(1, values.size());
  EXPECT_EQ(kWallClock1, values[0]);
}

TEST_F(ServiceTest, SecurityLevel) {
  // Encrypted is better than not.
  service_->SetSecurity(Service::kCryptoNone, false, false);
  service2_->SetSecurity(Service::kCryptoRc4, false, false);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());

  // AES encryption is better than RC4 encryption.
  service_->SetSecurity(Service::kCryptoRc4, false, false);
  service2_->SetSecurity(Service::kCryptoAes, false, false);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());

  // Crypto algorithm is more important than key rotation.
  service_->SetSecurity(Service::kCryptoNone, true, false);
  service2_->SetSecurity(Service::kCryptoAes, false, false);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());

  // Encrypted-but-unauthenticated is better than clear-but-authenticated.
  service_->SetSecurity(Service::kCryptoNone, false, true);
  service2_->SetSecurity(Service::kCryptoAes, false, false);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());

  // For same encryption, prefer key rotation.
  service_->SetSecurity(Service::kCryptoRc4, false, false);
  service2_->SetSecurity(Service::kCryptoRc4, true, false);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());

  // For same encryption, prefer authenticated AP.
  service_->SetSecurity(Service::kCryptoRc4, false, false);
  service2_->SetSecurity(Service::kCryptoRc4, false, true);
  EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
}

TEST_F(ServiceTest, SetErrorDetails) {
  EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
  static const char kDetails[] = "Certificate revoked.";
  ServiceMockAdaptor *adaptor = GetAdaptor();
  EXPECT_CALL(*adaptor, EmitStringChanged(kErrorDetailsProperty, kDetails));
  service_->SetErrorDetails(Service::kErrorDetailsNone);
  EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
  service_->SetErrorDetails(kDetails);
  EXPECT_EQ(kDetails, service_->error_details());
  service_->SetErrorDetails(kDetails);
}

TEST_F(ServiceTest, SetAutoConnectFull) {
  EXPECT_FALSE(service_->auto_connect());
  Error error;
  EXPECT_FALSE(GetAutoConnect(&error));
  EXPECT_TRUE(error.IsSuccess());

  // false -> false
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  SetAutoConnectFull(false, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_FALSE(GetAutoConnect(nullptr));
  Mock::VerifyAndClearExpectations(&mock_manager_);

  // Clear the |retain_auto_connect_| flag for the next test.
  service_->Unload();
  ASSERT_FALSE(service_->retain_auto_connect());

  // false -> true
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
  SetAutoConnectFull(true, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_TRUE(GetAutoConnect(nullptr));
  EXPECT_TRUE(service_->retain_auto_connect());
  Mock::VerifyAndClearExpectations(&mock_manager_);

  // Clear the |retain_auto_connect_| flag for the next test.
  service_->Unload();
  ASSERT_FALSE(service_->retain_auto_connect());

  // true -> true
  service_->SetAutoConnect(true);
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  SetAutoConnectFull(true, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_TRUE(GetAutoConnect(nullptr));
  EXPECT_TRUE(service_->retain_auto_connect());
  Mock::VerifyAndClearExpectations(&mock_manager_);

  // Clear the |retain_auto_connect_| flag for the next test.
  service_->Unload();
  ASSERT_FALSE(service_->retain_auto_connect());

  // true -> false
  service_->SetAutoConnect(true);
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
  SetAutoConnectFull(false, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_FALSE(GetAutoConnect(nullptr));
  EXPECT_TRUE(service_->retain_auto_connect());
  Mock::VerifyAndClearExpectations(&mock_manager_);
}

TEST_F(ServiceTest, SetAutoConnectFullUserUpdatePersists) {
  // If the user sets the kAutoConnectProperty explicitly, the preference must
  // be persisted, even if the property was not changed.
  Error error;
  MockProfileRefPtr mock_profile(
      new MockProfile(control_interface(), metrics(), &mock_manager_));
  NiceMock<MockStore> storage;
  service_->set_profile(mock_profile);
  service_->SetAutoConnect(true);

  EXPECT_CALL(*mock_profile, UpdateService(_));
  EXPECT_CALL(*mock_profile, GetConstStorage())
      .WillOnce(Return(&storage));
  EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
      .WillOnce(Return(false));
  EXPECT_FALSE(service_->retain_auto_connect());
  SetAutoConnectFull(true, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(service_->auto_connect());
  EXPECT_TRUE(service_->retain_auto_connect());
}

TEST_F(ServiceTest, ClearAutoConnect) {
  EXPECT_FALSE(service_->auto_connect());
  Error error;
  EXPECT_FALSE(GetAutoConnect(&error));
  EXPECT_TRUE(error.IsSuccess());

  // unset -> false
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  ClearAutoConnect(&error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_FALSE(GetAutoConnect(nullptr));
  Mock::VerifyAndClearExpectations(&mock_manager_);

  // false -> false
  SetAutoConnectFull(false, &error);
  EXPECT_FALSE(GetAutoConnect(nullptr));
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  ClearAutoConnect(&error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_FALSE(GetAutoConnect(nullptr));
  Mock::VerifyAndClearExpectations(&mock_manager_);

  // true -> false
  SetAutoConnectFull(true, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(GetAutoConnect(nullptr));
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
  ClearAutoConnect(&error);
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_FALSE(GetAutoConnect(nullptr));
  Mock::VerifyAndClearExpectations(&mock_manager_);
}

TEST_F(ServiceTest, UniqueAttributes) {
  EXPECT_NE(service_->serial_number_, service2_->serial_number_);
  EXPECT_NE(service_->unique_name(), service2_->unique_name());
}

TEST_F(ServiceTest, PropertyChanges) {
  TestCommonPropertyChanges(service_, GetAdaptor());
  TestAutoConnectPropertyChange(service_, GetAdaptor());
}

// Custom property setters should return false, and make no changes, if
// the new value is the same as the old value.
TEST_F(ServiceTest, CustomSetterNoopChange) {
  TestCustomSetterNoopChange(service_, &mock_manager_);
}

TEST_F(ServiceTest, GetTethering) {
  Error error;
  EXPECT_EQ("", service_->GetTethering(&error));
  EXPECT_EQ(Error::kNotSupported, error.type());
}

class ServiceWithMockOnPropertyChanged : public ServiceUnderTest {
 public:
  ServiceWithMockOnPropertyChanged(ControlInterface *control_interface,
                                   EventDispatcher *dispatcher,
                                   Metrics *metrics,
                                   Manager *manager)
      : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {}
  MOCK_METHOD1(OnPropertyChanged, void(const string &property));
};

TEST_F(ServiceTest, ConfigureServiceTriggersOnPropertyChanged) {
  auto service(make_scoped_refptr(
      new ServiceWithMockOnPropertyChanged(control_interface(),
                                           dispatcher(),
                                           metrics(),
                                           &mock_manager_)));
  KeyValueStore args;
  args.SetString(kUIDataProperty, "terpsichorean ejectamenta");
  args.SetBool(kSaveCredentialsProperty, false);

  // Calling Configure with different values from before triggers a single
  // OnPropertyChanged call per property.
  EXPECT_CALL(*service, OnPropertyChanged(kUIDataProperty)).Times(1);
  EXPECT_CALL(*service, OnPropertyChanged(kSaveCredentialsProperty)).Times(1);
  {
    Error error;
    service->Configure(args, &error);
    EXPECT_TRUE(error.IsSuccess());
  }
  Mock::VerifyAndClearExpectations(service);

  // Calling Configure with the same values as before should not trigger
  // OnPropertyChanged().
  EXPECT_CALL(*service, OnPropertyChanged(_)).Times(0);
  {
    Error error;
    service->Configure(args, &error);
    EXPECT_TRUE(error.IsSuccess());
  }
}

TEST_F(ServiceTest, ClearExplicitlyDisconnected) {
  EXPECT_FALSE(GetExplicitlyDisconnected());
  EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
  service_->ClearExplicitlyDisconnected();
  Mock::VerifyAndClearExpectations(&mock_manager_);

  SetExplicitlyDisconnected(true);
  EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
  service_->ClearExplicitlyDisconnected();
  Mock::VerifyAndClearExpectations(&mock_manager_);
  EXPECT_FALSE(GetExplicitlyDisconnected());
}

}  // namespace shill
