// Copyright (c) 2012 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/wifi.h"

#include <netinet/ether.h>
#include <linux/if.h>
#include <sys/socket.h>
#include <linux/netlink.h>  // Needs typedefs from sys/socket.h.

#include <map>
#include <set>
#include <string>
#include <vector>

#include <base/file_util.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <base/stringprintf.h>
#include <base/string_number_conversions.h>
#include <base/string_split.h>
#include <base/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <dbus-c++/dbus.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/dbus_adaptor.h"
#include "shill/event_dispatcher.h"
#include "shill/geolocation_info.h"
#include "shill/ieee80211.h"
#include "shill/key_value_store.h"
#include "shill/logging.h"
#include "shill/manager.h"
#include "shill/mock_dbus_manager.h"
#include "shill/mock_device.h"
#include "shill/mock_device_info.h"
#include "shill/mock_dhcp_config.h"
#include "shill/mock_dhcp_provider.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_link_monitor.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_profile.h"
#include "shill/mock_rtnl_handler.h"
#include "shill/mock_store.h"
#include "shill/mock_supplicant_bss_proxy.h"
#include "shill/mock_supplicant_interface_proxy.h"
#include "shill/mock_supplicant_network_proxy.h"
#include "shill/mock_supplicant_process_proxy.h"
#include "shill/mock_time.h"
#include "shill/mock_wifi_service.h"
#include "shill/nice_mock_control.h"
#include "shill/property_store_unittest.h"
#include "shill/proxy_factory.h"
#include "shill/wifi_endpoint.h"
#include "shill/wifi_service.h"
#include "shill/wpa_supplicant.h"


using std::map;
using std::set;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::DefaultValue;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Test;
using ::testing::Throw;
using ::testing::Values;

namespace shill {

class WiFiPropertyTest : public PropertyStoreTest {
 public:
  WiFiPropertyTest()
      : device_(new WiFi(control_interface(),
                         NULL, NULL, NULL, "wifi", "", 0)) {
  }
  virtual ~WiFiPropertyTest() {}

 protected:
  WiFiRefPtr device_;
};

TEST_F(WiFiPropertyTest, Contains) {
  EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
  EXPECT_FALSE(device_->store().Contains(""));
}

TEST_F(WiFiPropertyTest, SetProperty) {
  {
    ::DBus::Error error;
    EXPECT_TRUE(DBusAdaptor::SetProperty(
        device_->mutable_store(),
        flimflam::kBgscanSignalThresholdProperty,
        PropertyStoreTest::kInt32V,
        &error));
  }
  {
    ::DBus::Error error;
    EXPECT_TRUE(DBusAdaptor::SetProperty(device_->mutable_store(),
                                         flimflam::kScanIntervalProperty,
                                         PropertyStoreTest::kUint16V,
                                         &error));
  }
  // Ensure that an attempt to write a R/O property returns InvalidArgs error.
  {
    ::DBus::Error error;
    EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
                                          flimflam::kScanningProperty,
                                          PropertyStoreTest::kBoolV,
                                          &error));
    EXPECT_EQ(invalid_args(), error.name());
  }

  {
    ::DBus::Error error;
    EXPECT_TRUE(DBusAdaptor::SetProperty(
        device_->mutable_store(),
        flimflam::kBgscanMethodProperty,
        DBusAdaptor::StringToVariant(
            wpa_supplicant::kNetworkBgscanMethodSimple),
        &error));
  }

  {
    ::DBus::Error error;
    EXPECT_FALSE(DBusAdaptor::SetProperty(
        device_->mutable_store(),
        flimflam::kBgscanMethodProperty,
        DBusAdaptor::StringToVariant("not a real scan method"),
        &error));
  }
}

TEST_F(WiFiPropertyTest, BgscanMethodProperty) {
  EXPECT_NE(wpa_supplicant::kNetworkBgscanMethodLearn,
            WiFi::kDefaultBgscanMethod);
  EXPECT_TRUE(device_->bgscan_method_.empty());

  string method;
  Error unused_error;
  EXPECT_TRUE(device_->store().GetStringProperty(
      flimflam::kBgscanMethodProperty, &method, &unused_error));
  EXPECT_EQ(WiFi::kDefaultBgscanMethod, method);
  EXPECT_EQ(wpa_supplicant::kNetworkBgscanMethodSimple, method);

  ::DBus::Error error;
  EXPECT_TRUE(DBusAdaptor::SetProperty(
      device_->mutable_store(),
      flimflam::kBgscanMethodProperty,
      DBusAdaptor::StringToVariant(
          wpa_supplicant::kNetworkBgscanMethodLearn),
      &error));
  EXPECT_EQ(wpa_supplicant::kNetworkBgscanMethodLearn, device_->bgscan_method_);
  EXPECT_TRUE(device_->store().GetStringProperty(
      flimflam::kBgscanMethodProperty, &method, &unused_error));
  EXPECT_EQ(wpa_supplicant::kNetworkBgscanMethodLearn, method);

  EXPECT_TRUE(DBusAdaptor::ClearProperty(
      device_->mutable_store(), flimflam::kBgscanMethodProperty, &error));
  EXPECT_TRUE(device_->store().GetStringProperty(
      flimflam::kBgscanMethodProperty, &method, &unused_error));
  EXPECT_EQ(WiFi::kDefaultBgscanMethod, method);
  EXPECT_TRUE(device_->bgscan_method_.empty());
}

class WiFiObjectTest : public ::testing::TestWithParam<string> {
 public:
  WiFiObjectTest(EventDispatcher *dispatcher)
      : event_dispatcher_(dispatcher),
        manager_(&control_interface_, NULL, &metrics_, &glib_),
        device_info_(&control_interface_, dispatcher, &metrics_, &manager_),
        wifi_(new WiFi(&control_interface_,
                       dispatcher,
                       &metrics_,
                       &manager_,
                       kDeviceName,
                       kDeviceAddress,
                       0)),
        supplicant_process_proxy_(new NiceMock<MockSupplicantProcessProxy>()),
        supplicant_interface_proxy_(
            new NiceMock<MockSupplicantInterfaceProxy>(wifi_)),
        supplicant_bss_proxy_(
            new NiceMock<MockSupplicantBSSProxy>()),
        dhcp_config_(new MockDHCPConfig(&control_interface_,
                                        kDeviceName)),
        dbus_manager_(new NiceMock<MockDBusManager>()),
        proxy_factory_(this) {
    ::testing::DefaultValue< ::DBus::Path>::Set("/default/path");
    // Except for WiFiServices created via WiFi::GetService, we expect
    // that any WiFiService has been registered with the Manager. So
    // default Manager.HasService to true, to make the common case
    // easy.
    ON_CALL(manager_, HasService(_)).
        WillByDefault(Return(true));

    ON_CALL(dhcp_provider_, CreateConfig(_, _, _, _)).
        WillByDefault(Return(dhcp_config_));
    ON_CALL(*dhcp_config_.get(), RequestIP()).
        WillByDefault(Return(true));
    ON_CALL(proxy_factory_, CreateSupplicantNetworkProxy(_, _)).
        WillByDefault(InvokeWithoutArgs(
            this, &WiFiObjectTest::CreateSupplicantNetworkProxy));

    manager_.dbus_manager_.reset(dbus_manager_);  // Transfers ownership.

    wifi_->time_ = &time_;
  }

  virtual void SetUp() {
    // EnableScopes... so that we can EXPECT_CALL for scoped log messages.
    ScopeLogger::GetInstance()->EnableScopesByName("wifi");
    ScopeLogger::GetInstance()->set_verbose_level(3);
    wifi_->proxy_factory_ = &proxy_factory_;
    static_cast<Device *>(wifi_)->rtnl_handler_ = &rtnl_handler_;
    wifi_->set_dhcp_provider(&dhcp_provider_);
    ON_CALL(manager_, device_info()).
        WillByDefault(Return(&device_info_));
    EXPECT_CALL(manager_, UpdateEnabledTechnologies()).Times(AnyNumber());
    EXPECT_CALL(manager_, DeregisterService(_)).Times(AnyNumber());
    EXPECT_CALL(*supplicant_bss_proxy_, Die()).Times(AnyNumber());
  }

  virtual void TearDown() {
    EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
    wifi_->SelectService(NULL);
    if (supplicant_bss_proxy_.get()) {
      EXPECT_CALL(*supplicant_bss_proxy_, Die());
    }
    wifi_->proxy_factory_ = NULL;
    // must Stop WiFi instance, to clear its list of services.
    // otherwise, the WiFi instance will not be deleted. (because
    // services reference a WiFi instance, creating a cycle.)
    wifi_->Stop(NULL, ResultCallback());
    wifi_->set_dhcp_provider(NULL);
    // Reset scope logging, to avoid interfering with other tests.
    ScopeLogger::GetInstance()->EnableScopesByName("-wifi");
    ScopeLogger::GetInstance()->set_verbose_level(0);
  }

  // Needs to be public since it is called via Invoke().
  void StopWiFi() {
    wifi_->SetEnabled(false);  // Stop(NULL, ResultCallback());
  }

  // Needs to be public since it is called via Invoke().
  void ThrowDBusError() {
    throw DBus::Error("SomeDBusType", "A handy message");
  }

  void UnloadService(const ServiceRefPtr &service) {
    service->Unload();
  }

 protected:
  typedef scoped_refptr<MockWiFiService> MockWiFiServiceRefPtr;

  class TestProxyFactory : public ProxyFactory {
   public:
    explicit TestProxyFactory(WiFiObjectTest *test);

    virtual SupplicantProcessProxyInterface *CreateSupplicantProcessProxy(
        const char */*dbus_path*/, const char */*dbus_addr*/) {
      return test_->supplicant_process_proxy_.release();
    }

    virtual SupplicantInterfaceProxyInterface *CreateSupplicantInterfaceProxy(
        const WiFiRefPtr &/*wifi*/,
        const DBus::Path &/*object_path*/,
        const char */*dbus_addr*/) {
      return test_->supplicant_interface_proxy_.release();
    }

    MOCK_METHOD3(CreateSupplicantBSSProxy,
                 SupplicantBSSProxyInterface *(
                     WiFiEndpoint *wifi_endpoint,
                     const DBus::Path &object_path,
                     const char *dbus_addr));

    MOCK_METHOD2(CreateSupplicantNetworkProxy,
                 SupplicantNetworkProxyInterface *(
                     const DBus::Path &object_path,
                     const char *dbus_addr));

   private:
    SupplicantBSSProxyInterface *CreateSupplicantBSSProxyInternal(
        WiFiEndpoint */*wifi_endpoint*/,
        const DBus::Path &/*object_path*/,
        const char */*dbus_addr*/) {
      return test_->supplicant_bss_proxy_.release();
    }

    WiFiObjectTest *test_;
  };

  void CancelScanTimer() {
    wifi_->scan_timer_callback_.Cancel();
  }
  WiFiServiceRefPtr CreateServiceForEndpoint(const WiFiEndpoint &endpoint) {
    bool hidden_ssid = false;
    return wifi_->CreateServiceForEndpoint(endpoint, hidden_ssid);
  }
  void FireScanTimer() {
    wifi_->ScanTimerHandler();
  }
  void TriggerScan() {
    wifi_->Scan(NULL);
  }
  const WiFiServiceRefPtr &GetCurrentService() {
    return wifi_->current_service_;
  }
  void SetCurrentService(const WiFiServiceRefPtr &service) {
    wifi_->current_service_ = service;
  }
  const WiFi::EndpointMap &GetEndpointMap() {
    return wifi_->endpoint_by_rpcid_;
  }
  const WiFiServiceRefPtr &GetPendingService() {
    return wifi_->pending_service_;
  }
  const base::CancelableClosure &GetPendingTimeout() {
    return wifi_->pending_timeout_callback_;
  }
  const base::CancelableClosure &GetReconnectTimeoutCallback() {
    return wifi_->reconnect_timeout_callback_;
  }
  int GetReconnectTimeoutSeconds() {
    return WiFi::kReconnectTimeoutSeconds;
  }
  const base::CancelableClosure &GetScanTimer() {
    return wifi_->scan_timer_callback_;
  }
  const vector<WiFiServiceRefPtr> &GetServices() {
    return wifi_->services_;
  }
  // note: the tests need the proxies referenced by WiFi (not the
  // proxies instantiated by WiFiObjectTest), to ensure that WiFi
  // sets up its proxies correctly.
  SupplicantProcessProxyInterface *GetSupplicantProcessProxy() {
    return wifi_->supplicant_process_proxy_.get();
  }
  MockSupplicantInterfaceProxy *GetSupplicantInterfaceProxy() {
    return dynamic_cast<MockSupplicantInterfaceProxy *>(
        wifi_->supplicant_interface_proxy_.get());
  }
  MockSupplicantNetworkProxy *CreateSupplicantNetworkProxy() {
    return new NiceMock<MockSupplicantNetworkProxy>();
  }
  const string &GetSupplicantState() {
    return wifi_->supplicant_state_;
  }
  void InitiateConnect(WiFiServiceRefPtr service) {
    map<string, ::DBus::Variant> params;
    wifi_->ConnectTo(service, params);
  }
  void InitiateDisconnect(WiFiServiceRefPtr service) {
    wifi_->DisconnectFrom(service);
  }
  WiFiEndpointRefPtr MakeEndpoint(const string &ssid, const string &bssid) {
    return WiFiEndpoint::MakeOpenEndpoint(
        &proxy_factory_, NULL, ssid, bssid, 0, 0);
  }
  MockWiFiServiceRefPtr MakeMockService(const std::string &security) {
    vector<uint8_t> ssid(1, 'a');
    return new MockWiFiService(
        &control_interface_,
        event_dispatcher_,
        &metrics_,
        &manager_,
        wifi_,
        ssid,
        flimflam::kModeManaged,
        security,
        false);
  }
  void ClearCachedCredentials(const WiFiService *service) {
    return wifi_->ClearCachedCredentials(service);
  }
  bool RemoveNetwork(const ::DBus::Path &network) {
    return wifi_->RemoveNetwork(network);
  }
  void RemoveBSS(const ::DBus::Path &bss_path);
  void ReportBSS(const ::DBus::Path &bss_path,
                 const string &ssid,
                 const string &bssid,
                 int16_t signal_strength,
                 uint16 frequency,
                 const char *mode);
  void ReportIPConfigComplete() {
    wifi_->OnIPConfigUpdated(dhcp_config_, true);
  }
  void ReportLinkUp() {
    wifi_->LinkEvent(IFF_LOWER_UP, IFF_LOWER_UP);
  }
  void ReportScanDone() {
    wifi_->ScanDoneTask();
  }
  void ReportCurrentBSSChanged(const string &new_bss) {
    wifi_->CurrentBSSChanged(new_bss);
  }
  void ReportStateChanged(const string &new_state) {
    wifi_->StateChanged(new_state);
  }
  void ReportWiFiDebugScopeChanged(bool enabled) {
    wifi_->OnWiFiDebugScopeChanged(enabled);
  }
  void SetPendingService(const WiFiServiceRefPtr &service) {
    wifi_->pending_service_ = service;
  }
  void SetScanInterval(uint16_t interval_seconds) {
    wifi_->SetScanInterval(interval_seconds, NULL);
  }
  uint16_t GetScanInterval() {
    return wifi_->GetScanInterval(NULL);
  }
  void StartWiFi(bool supplicant_present) {
    wifi_->supplicant_present_ = supplicant_present;
    wifi_->SetEnabled(true);  // Start(NULL, ResultCallback());
  }
  void StartWiFi() {
    StartWiFi(true);
  }
  void OnAfterResume() {
    wifi_->OnAfterResume();
  }
  void OnBeforeSuspend() {
    wifi_->OnBeforeSuspend();
  }
  void OnSupplicantAppear() {
    wifi_->OnSupplicantAppear(":1.7");
    EXPECT_TRUE(wifi_->supplicant_present_);
  }
  void OnSupplicantVanish() {
    wifi_->OnSupplicantVanish();
    EXPECT_FALSE(wifi_->supplicant_present_);
  }
  bool GetSupplicantPresent() {
    return wifi_->supplicant_present_;
  }
  WiFiServiceRefPtr GetOpenService(const char *service_type,
                                   const char *ssid,
                                   const char *mode,
                                   Error *result) {
    return GetServiceInner(service_type, ssid, mode, NULL, NULL, false, result);
  }
  WiFiServiceRefPtr GetService(const char *service_type,
                               const char *ssid,
                               const char *mode,
                               const char *security,
                               const char *passphrase,
                               Error *result) {
    return GetServiceInner(service_type, ssid, mode, security, passphrase,
                           false, result);
  }
  WiFiServiceRefPtr GetServiceInner(const char *service_type,
                                    const char *ssid,
                                    const char *mode,
                                    const char *security,
                                    const char *passphrase,
                                    bool allow_hidden,
                                    Error *result) {
    map<string, ::DBus::Variant> args;
    // in general, we want to avoid D-Bus specific code for any RPCs
    // that come in via adaptors. we make an exception here, because
    // calls to GetWifiService are rerouted from the Manager object to
    // the Wifi class.
    if (service_type != NULL)
      args[flimflam::kTypeProperty].writer().append_string(service_type);
    if (ssid != NULL)
      args[flimflam::kSSIDProperty].writer().append_string(ssid);
    if (mode != NULL)
      args[flimflam::kModeProperty].writer().append_string(mode);
    if (security != NULL)
      args[flimflam::kSecurityProperty].writer().append_string(security);
    if (passphrase != NULL)
      args[flimflam::kPassphraseProperty].writer().append_string(passphrase);
    if (!allow_hidden)
      args[flimflam::kWifiHiddenSsid].writer().append_bool(false);

    Error e;
    KeyValueStore args_kv;
    DBusAdaptor::ArgsToKeyValueStore(args, &args_kv, &e);
    WiFiServiceRefPtr service = wifi_->GetService(args_kv, result);
    if (service) {
      service->Configure(args_kv, result);
    }
    return service;
  }

  WiFiServiceRefPtr GetServiceWithKeyValues(const KeyValueStore &args,
                                            Error *result) {
    return wifi_->GetService(args, result);
  }

  WiFiServiceRefPtr FindService(const vector<uint8_t> &ssid,
                                const string &mode,
                                const string &security) {
    return wifi_->FindService(ssid, mode, security);
  }
  bool LoadHiddenServices(StoreInterface *storage) {
    return wifi_->LoadHiddenServices(storage);
  }
  void SetupHiddenStorage(MockStore *storage, const string &ssid, string *id) {
    const string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
    *id = StringToLowerASCII(base::StringPrintf("%s_%s_%s_%s_%s",
                                                flimflam::kTypeWifi,
                                                kDeviceAddress,
                                                hex_ssid.c_str(),
                                                flimflam::kModeManaged,
                                                flimflam::kSecurityNone));
    const char *groups[] = { id->c_str() };
    EXPECT_CALL(*storage, GetGroupsWithKey(flimflam::kWifiHiddenSsid))
        .WillRepeatedly(Return(set<string>(groups, groups + 1)));
    EXPECT_CALL(*storage, GetBool(StrEq(*id), flimflam::kWifiHiddenSsid, _))
        .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
    EXPECT_CALL(*storage, GetString(StrEq(*id), flimflam::kSSIDProperty, _))
        .WillRepeatedly(DoAll(SetArgumentPointee<2>(hex_ssid), Return(true)));
  }

  WiFiService *SetupConnectedService(const DBus::Path &network_path) {
    EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
    EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
    EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
    EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
    if (!network_path.empty()) {
      EXPECT_CALL(*supplicant_interface_proxy_, AddNetwork(_))
          .WillOnce(Return(network_path));
    }

    StartWiFi();
    ReportBSS(kBSSName, kSSIDName, "00:00:00:00:00:00", 0, 0,
              kNetworkModeAdHoc);
    WiFiService *service(GetServices().begin()->get());
    EXPECT_TRUE(GetPendingTimeout().IsCancelled());
    InitiateConnect(service);
    EXPECT_FALSE(GetPendingTimeout().IsCancelled());
    ReportCurrentBSSChanged(kBSSName);
    EXPECT_TRUE(GetPendingTimeout().IsCancelled());
    ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);

    EXPECT_EQ(service, GetCurrentService());

    return service;
  }

  bool SetBgscanMethod(const string &method) {
    ::DBus::Error error;
    return DBusAdaptor::SetProperty(
        wifi_->mutable_store(),
        flimflam::kBgscanMethodProperty,
        DBusAdaptor::StringToVariant(method),
        &error);
  }

  void AppendBgscan(WiFiService *service,
                    std::map<std::string, DBus::Variant> *service_params) {
    wifi_->AppendBgscan(service, service_params);
  }

  void ReportCertification(const map<string, ::DBus::Variant> &properties) {
    wifi_->CertificationTask(properties);
  }

  void ReportEAPEvent(const string &status, const string &parameter) {
    wifi_->EAPEventTask(status, parameter);
  }

  void RestartFastScanAttempts() {
    wifi_->RestartFastScanAttempts();
  }

  void StartReconnectTimer() {
    wifi_->StartReconnectTimer();
  }

  void StopReconnectTimer() {
    wifi_->StopReconnectTimer();
  }

  void SetLinkMonitor(LinkMonitor *link_monitor) {
    wifi_->set_link_monitor(link_monitor);
  }

  bool SuspectCredentials(const WiFiService &service,
                          Service::ConnectFailure *failure) {
    return wifi_->SuspectCredentials(service, failure);
  }

  void OnLinkMonitorFailure() {
    wifi_->OnLinkMonitorFailure();
  }

  NiceMockControl *control_interface() {
    return &control_interface_;
  }

  MockManager *manager() {
    return &manager_;
  }

  MockDeviceInfo *device_info() {
    return &device_info_;
  }

  MockDHCPProvider *dhcp_provider() {
    return &dhcp_provider_;
  }

  const WiFiConstRefPtr wifi() const {
    return wifi_;
  }

  TestProxyFactory *proxy_factory() {
    return &proxy_factory_;
  }

  EventDispatcher *event_dispatcher_;
  NiceMock<MockRTNLHandler> rtnl_handler_;
  MockTime time_;

 private:
  NiceMockControl control_interface_;
  MockMetrics metrics_;
  MockGLib glib_;
  MockManager manager_;
  MockDeviceInfo device_info_;
  WiFiRefPtr wifi_;

  // protected fields interspersed between private fields, due to
  // initialization order
 protected:
  static const char kDeviceName[];
  static const char kDeviceAddress[];
  static const char kNetworkModeAdHoc[];
  static const char kNetworkModeInfrastructure[];
  static const char kBSSName[];
  static const char kSSIDName[];

  scoped_ptr<MockSupplicantProcessProxy> supplicant_process_proxy_;
  scoped_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
  scoped_ptr<MockSupplicantBSSProxy> supplicant_bss_proxy_;
  MockDHCPProvider dhcp_provider_;
  scoped_refptr<MockDHCPConfig> dhcp_config_;
  NiceMock<MockDBusManager> *dbus_manager_;

 private:
  NiceMock<TestProxyFactory> proxy_factory_;
};

const char WiFiObjectTest::kDeviceName[] = "wlan0";
const char WiFiObjectTest::kDeviceAddress[] = "000102030405";
const char WiFiObjectTest::kNetworkModeAdHoc[] = "ad-hoc";
const char WiFiObjectTest::kNetworkModeInfrastructure[] = "infrastructure";
const char WiFiObjectTest::kBSSName[] = "bss0";
const char WiFiObjectTest::kSSIDName[] = "ssid0";

void WiFiObjectTest::RemoveBSS(const ::DBus::Path &bss_path) {
  wifi_->BSSRemovedTask(bss_path);
}

void WiFiObjectTest::ReportBSS(const ::DBus::Path &bss_path,
                             const string &ssid,
                             const string &bssid,
                             int16_t signal_strength,
                             uint16 frequency,
                             const char *mode) {
  map<string, ::DBus::Variant> bss_properties;

  {
    DBus::MessageIter writer(bss_properties["SSID"].writer());
    writer << vector<uint8_t>(ssid.begin(), ssid.end());
  }
  {
    string bssid_nosep;
    vector<uint8_t> bssid_bytes;
    RemoveChars(bssid, ":", &bssid_nosep);
    base::HexStringToBytes(bssid_nosep, &bssid_bytes);

    DBus::MessageIter writer(bss_properties["BSSID"].writer());
    writer << bssid_bytes;
  }
  bss_properties[wpa_supplicant::kBSSPropertySignal].writer().
      append_int16(signal_strength);
  bss_properties[wpa_supplicant::kBSSPropertyFrequency].writer().
      append_uint16(frequency);
  bss_properties[wpa_supplicant::kBSSPropertyMode].writer().append_string(mode);
  wifi_->BSSAddedTask(bss_path, bss_properties);
}

WiFiObjectTest::TestProxyFactory::TestProxyFactory(WiFiObjectTest *test)
    : test_(test) {
  EXPECT_CALL(*this, CreateSupplicantBSSProxy(_, _, _)).Times(AnyNumber());
  ON_CALL(*this, CreateSupplicantBSSProxy(_, _, _))
      .WillByDefault(
          Invoke(this, (&TestProxyFactory::CreateSupplicantBSSProxyInternal)));
}

// Most of our tests involve using a real EventDispatcher object.
class WiFiMainTest : public WiFiObjectTest {
 public:
  WiFiMainTest() : WiFiObjectTest(&dispatcher_) {}

 protected:
  EventDispatcher dispatcher_;
};

TEST_F(WiFiMainTest, ProxiesSetUpDuringStart) {
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);
  EXPECT_TRUE(GetSupplicantInterfaceProxy() == NULL);

  StartWiFi();
  EXPECT_FALSE(GetSupplicantProcessProxy() == NULL);
  EXPECT_FALSE(GetSupplicantInterfaceProxy() == NULL);
}

TEST_F(WiFiMainTest, SupplicantPresent) {
  EXPECT_FALSE(GetSupplicantPresent());
}

TEST_F(WiFiMainTest, OnSupplicantAppearStarted) {
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);

  EXPECT_CALL(*dbus_manager_, WatchName(wpa_supplicant::kDBusAddr, _, _));
  StartWiFi(false);  // No supplicant present.
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);

  OnSupplicantAppear();
  EXPECT_FALSE(GetSupplicantProcessProxy() == NULL);

  // If supplicant reappears while the device is started, the device should be
  // restarted.
  EXPECT_CALL(*manager(), DeregisterDevice(_));
  EXPECT_CALL(*manager(), RegisterDevice(_));
  OnSupplicantAppear();
}

TEST_F(WiFiMainTest, OnSupplicantAppearStopped) {
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);

  OnSupplicantAppear();
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);

  // If supplicant reappears while the device is stopped, the device should not
  // be restarted.
  EXPECT_CALL(*manager(), DeregisterDevice(_)).Times(0);
  OnSupplicantAppear();
}

TEST_F(WiFiMainTest, OnSupplicantVanishStarted) {
  EXPECT_TRUE(GetSupplicantProcessProxy() == NULL);

  StartWiFi();
  EXPECT_FALSE(GetSupplicantProcessProxy() == NULL);
  EXPECT_TRUE(GetSupplicantPresent());

  EXPECT_CALL(*manager(), DeregisterDevice(_));
  EXPECT_CALL(*manager(), RegisterDevice(_));
  OnSupplicantVanish();
}

TEST_F(WiFiMainTest, OnSupplicantVanishStopped) {
  OnSupplicantAppear();
  EXPECT_TRUE(GetSupplicantPresent());
  EXPECT_CALL(*manager(), DeregisterDevice(_)).Times(0);
  OnSupplicantVanish();
}

TEST_F(WiFiMainTest, OnSupplicantVanishedWhileConnected) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  WiFiService *service(SetupConnectedService(DBus::Path()));
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith("silently resetting current_service_.")));
  EXPECT_CALL(*manager(), DeregisterDevice(_))
      .WillOnce(InvokeWithoutArgs(this, &WiFiObjectTest::StopWiFi));
  EXPECT_CALL(*manager(), DeregisterService(ServiceRefPtr(service)))
      .WillOnce(Invoke(this, &WiFiObjectTest::UnloadService));
  EXPECT_CALL(supplicant_interface_proxy, Disconnect()).Times(0);
  EXPECT_CALL(*manager(), RegisterDevice(_));
  OnSupplicantVanish();
  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, CleanStart) {
  EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_));
  EXPECT_CALL(*supplicant_process_proxy_, GetInterface(_))
      .Times(AnyNumber())
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.InterfaceUnknown",
              "test threw fi.w1.wpa_supplicant1.InterfaceUnknown")));
  EXPECT_CALL(*manager(), LoadDeviceFromProfiles(_));
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
  EXPECT_TRUE(GetScanTimer().IsCancelled());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ClearCachedCredentials) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  DBus::Path network = "/test/path";
  WiFiService *service(SetupConnectedService(network));
  EXPECT_CALL(supplicant_interface_proxy, RemoveNetwork(network));
  ClearCachedCredentials(service);
}

TEST_F(WiFiMainTest, RemoveNetwork) {
  DBus::Path network = "/test/path";
  EXPECT_CALL(*supplicant_interface_proxy_, RemoveNetwork(network));
  StartWiFi();
  EXPECT_TRUE(RemoveNetwork(network));
}

TEST_F(WiFiMainTest, RemoveNetworkWhenSupplicantReturnsNetworkUnknown) {
  DBus::Path network = "/test/path";
  EXPECT_CALL(*supplicant_interface_proxy_, RemoveNetwork(network))
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.NetworkUnknown",
              "test threw fi.w1.wpa_supplicant1.NetworkUnknown")));
  StartWiFi();
  EXPECT_TRUE(RemoveNetwork(network));
}

TEST_F(WiFiMainTest, UseArpGateway) {
  EXPECT_CALL(dhcp_provider_, CreateConfig(kDeviceName, _, _, true))
      .WillOnce(Return(dhcp_config_));
  const_cast<WiFi *>(wifi().get())->AcquireIPConfig();
}

TEST_F(WiFiMainTest, RemoveNetworkWhenSupplicantReturnsInvalidArgs) {
  DBus::Path network = "/test/path";
  EXPECT_CALL(*supplicant_interface_proxy_, RemoveNetwork(network))
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.InvalidArgs",
              "test threw fi.w1.wpa_supplicant1.InvalidArgs")));
  StartWiFi();
  EXPECT_FALSE(RemoveNetwork(network));
}

TEST_F(WiFiMainTest, RemoveNetworkWhenSupplicantReturnsUnknownError) {
  DBus::Path network = "/test/path";
  EXPECT_CALL(*supplicant_interface_proxy_, RemoveNetwork(network))
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.UnknownError",
              "test threw fi.w1.wpa_supplicant1.UnknownError")));
  StartWiFi();
  EXPECT_FALSE(RemoveNetwork(network));
}

TEST_F(WiFiMainTest, Restart) {
  EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_))
      .Times(AnyNumber())
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.InterfaceExists",
              "test threw fi.w1.wpa_supplicant1.InterfaceExists")));
  EXPECT_CALL(*supplicant_process_proxy_, GetInterface(_));
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, StartClearsState) {
  EXPECT_CALL(*supplicant_interface_proxy_, RemoveAllNetworks());
  EXPECT_CALL(*supplicant_interface_proxy_, FlushBSS(_));
  StartWiFi();
}

TEST_F(WiFiMainTest, NoScansWhileConnecting) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  StartWiFi();
  SetPendingService(service);
  // If we're connecting, we ignore scan requests to stay on channel.
  service->state_ = Service::kStateConfiguring;
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  TriggerScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  // But otherwise we'll honor the request.
  service->state_ = Service::kStateConnected;
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  TriggerScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  // Similarly, ignore scans when our connected service is reconnecting.
  SetPendingService(NULL);
  SetCurrentService(service);
  service->state_ = Service::kStateAssociating;
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  TriggerScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  // But otherwise we'll honor the request.
  service->state_ = Service::kStateIdle;
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  TriggerScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
}

TEST_F(WiFiMainTest, ResumeStartsScanWhenIdle) {
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
  ReportScanDone();
  ASSERT_TRUE(wifi()->IsIdle());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
  OnAfterResume();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, SuspendDoesNotStartScan) {
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
  ASSERT_TRUE(wifi()->IsIdle());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  OnBeforeSuspend();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ResumeDoesNotStartScanWhenNotIdle) {
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_));
  StartWiFi();

  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
  Error error;
  ScopedMockLog log;
  service->AddEndpoint(ap);
  service->AutoConnect();
  service->SetState(Service::kStateOnline);
  EXPECT_FALSE(wifi()->IsIdle());
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
  ASSERT_FALSE(wifi()->IsIdle());
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, EndsWith("already scanning or connected.")));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  OnAfterResume();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ScanResults) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS(
      "bss1", "ssid1", "00:00:00:00:00:01", 1, 0, kNetworkModeInfrastructure);
  ReportBSS(
      "bss2", "ssid2", "00:00:00:00:00:02", 2, 0, kNetworkModeInfrastructure);
  ReportBSS(
      "bss3", "ssid3", "00:00:00:00:00:03", 3, 0, kNetworkModeInfrastructure);
  const uint16 frequency = 2412;
  ReportBSS("bss4", "ssid4", "00:00:00:00:00:04", 4, frequency,
            kNetworkModeAdHoc);

  const WiFi::EndpointMap &endpoints_by_rpcid = GetEndpointMap();
  EXPECT_EQ(5, endpoints_by_rpcid.size());

  WiFi::EndpointMap::const_iterator i;
  WiFiEndpointRefPtr endpoint;
  for (i = endpoints_by_rpcid.begin();
       i != endpoints_by_rpcid.end();
       ++i) {
    if (i->second->bssid_string() == "00:00:00:00:00:04")
      break;
  }
  ASSERT_TRUE(i != endpoints_by_rpcid.end());
  EXPECT_EQ(4, i->second->signal_strength());
  EXPECT_EQ(frequency, i->second->frequency());
  EXPECT_EQ("adhoc", i->second->network_mode());
}

TEST_F(WiFiMainTest, ScanResultsWithUpdates) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS(
      "bss1", "ssid1", "00:00:00:00:00:01", 1, 0, kNetworkModeInfrastructure);
  ReportBSS(
      "bss2", "ssid2", "00:00:00:00:00:02", 2, 0, kNetworkModeInfrastructure);
  ReportBSS(
      "bss1", "ssid1", "00:00:00:00:00:01", 3, 0, kNetworkModeInfrastructure);
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 4, 0, kNetworkModeAdHoc);

  const WiFi::EndpointMap &endpoints_by_rpcid = GetEndpointMap();
  EXPECT_EQ(3, endpoints_by_rpcid.size());

  WiFi::EndpointMap::const_iterator i;
  WiFiEndpointRefPtr endpoint;
  for (i = endpoints_by_rpcid.begin();
       i != endpoints_by_rpcid.end();
       ++i) {
    if (i->second->bssid_string() == "00:00:00:00:00:00")
      break;
  }
  ASSERT_TRUE(i != endpoints_by_rpcid.end());
  EXPECT_EQ(4, i->second->signal_strength());
}

TEST_F(WiFiMainTest, ScanCompleted) {
  StartWiFi();
  EXPECT_CALL(*manager(), RegisterService(_))
      .Times(3);
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS(
      "bss1", "ssid1", "00:00:00:00:00:01", 1, 0, kNetworkModeInfrastructure);
  ReportBSS(
      "bss2", "ssid2", "00:00:00:00:00:02", 2, 0, kNetworkModeInfrastructure);
  ReportScanDone();
  EXPECT_EQ(3, GetServices().size());

  // BSSes with SSIDs that start with NULL should be filtered.
  ReportBSS("bss3", string(1, 0), "00:00:00:00:00:03", 3, 0, kNetworkModeAdHoc);
  EXPECT_EQ(3, GetEndpointMap().size());
  EXPECT_EQ(3, GetServices().size());

  // BSSes with empty SSIDs should be filtered.
  ReportBSS("bss3", string(), "00:00:00:00:00:03", 3, 0, kNetworkModeAdHoc);
  EXPECT_EQ(3, GetEndpointMap().size());
  EXPECT_EQ(3, GetServices().size());
}

TEST_F(WiFiMainTest, EndpointGroupingTogether) {
  StartWiFi();

  InSequence s;
  EXPECT_CALL(*manager(), RegisterService(_));
  EXPECT_CALL(*manager(), HasService(_));
  EXPECT_CALL(*manager(), UpdateService(_));
  ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid", "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  EXPECT_EQ(1, GetServices().size());
}

TEST_F(WiFiMainTest, EndpointGroupingDifferentSSID) {
  StartWiFi();
  EXPECT_CALL(*manager(), RegisterService(_))
      .Times(2);
  ReportBSS("bss0", "ssid1", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid2", "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  EXPECT_EQ(2, GetServices().size());
}

TEST_F(WiFiMainTest, EndpointGroupingDifferentMode) {
  StartWiFi();
  EXPECT_CALL(*manager(), RegisterService(_))
      .Times(2);
  ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid", "00:00:00:00:00:01", 0, 0,
            kNetworkModeInfrastructure);
  ReportScanDone();
  EXPECT_EQ(2, GetServices().size());
}

TEST_F(WiFiMainTest, NonExistentBSSRemoved) {
  // Removal of non-existent BSS should not cause a crash.
  StartWiFi();
  RemoveBSS("bss0");
  EXPECT_EQ(0, GetServices().size());
}

TEST_F(WiFiMainTest, BSSWithEmptySSIDRemoved) {
  // Removal of BSS with an empty SSID should not cause a crash.
  ReportBSS("bss", string(), "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  StartWiFi();
  RemoveBSS("bss");
  EXPECT_EQ(0, GetServices().size());
}

TEST_F(WiFiMainTest, BSSWithNullSSIDRemoved) {
  // Removal of BSS with a NULL SSID should not cause a crash.
  ReportBSS("bss", string(1, 0), "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  StartWiFi();
  RemoveBSS("bss");
  EXPECT_EQ(0, GetServices().size());
}

TEST_F(WiFiMainTest, LoneBSSRemoved) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  StartWiFi();
  ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  EXPECT_EQ(1, GetServices().size());
  EXPECT_TRUE(GetServices().front()->IsVisible());

  EXPECT_CALL(*manager(), DeregisterService(_));
  RemoveBSS("bss0");
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnected) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  StartWiFi();
  ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  ReportCurrentBSSChanged("bss0");

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  EXPECT_CALL(*manager(), DeregisterService(_));
  RemoveBSS("bss0");
  EXPECT_TRUE(GetServices().empty());
}

TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnectedToHidden) {
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  StartWiFi();

  Error e;
  WiFiServiceRefPtr service =
      GetServiceInner(flimflam::kTypeWifi, "ssid", flimflam::kModeManaged,
                      NULL, NULL, true, &e);
  EXPECT_EQ(1, GetServices().size());

  ReportBSS("bss", "ssid", "00:00:00:00:00:01", 0, 0,
            kNetworkModeInfrastructure);
  ReportScanDone();
  ReportCurrentBSSChanged("bss");
  EXPECT_EQ(1, GetServices().size());

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  RemoveBSS("bss");
  EXPECT_EQ(1, GetServices().size());
  // Verify expectations now, because WiFi may call UpdateService when
  // WiFi is Stop()-ed (during TearDown()).
  Mock::VerifyAndClearExpectations(manager());
  EXPECT_CALL(*manager(), DeregisterService(_)).Times(AnyNumber());
}

TEST_F(WiFiMainTest, NonSolitaryBSSRemoved) {
  EXPECT_CALL(*manager(), RegisterService(_));
  EXPECT_CALL(*manager(), HasService(_));
  EXPECT_CALL(*manager(), UpdateService(_));
  StartWiFi();
  ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  EXPECT_EQ(1, GetServices().size());
  EXPECT_TRUE(GetServices().front()->IsVisible());

  EXPECT_CALL(*manager(), UpdateService(_));
  RemoveBSS("bss0");
  EXPECT_TRUE(GetServices().front()->IsVisible());
  EXPECT_EQ(1, GetServices().size());
}

TEST_F(WiFiMainTest, Connect) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();

  {
    InSequence s;
    DBus::Path fake_path("/fake/path");
    WiFiService *service(GetServices().begin()->get());

    EXPECT_CALL(supplicant_interface_proxy, AddNetwork(_))
        .WillOnce(Return(fake_path));
    EXPECT_CALL(supplicant_interface_proxy, SelectNetwork(fake_path));
    InitiateConnect(service);
    EXPECT_EQ(static_cast<Service *>(service),
              wifi()->selected_service_.get());
    EXPECT_EQ(Service::kStateAssociating, service->state());
    EXPECT_FALSE(GetPendingTimeout().IsCancelled());
  }
}

TEST_F(WiFiMainTest, ReconnectPreservesDBusPath) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();

  DBus::Path fake_path("/fake/path");
  WiFiService *service(GetServices().begin()->get());
  EXPECT_CALL(supplicant_interface_proxy, AddNetwork(_))
      .WillOnce(Return(fake_path));
  EXPECT_CALL(supplicant_interface_proxy, SelectNetwork(fake_path));
  InitiateConnect(service);

  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);

  // Return the service to a connectable state.
  InitiateDisconnect(service);

  // A second connection attempt should remember the DBus path associated
  // with this service.
  EXPECT_CALL(supplicant_interface_proxy, AddNetwork(_)).Times(0);
  EXPECT_CALL(supplicant_interface_proxy, SelectNetwork(fake_path));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, DisconnectPendingService) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  WiFiService *service(GetServices().begin()->get());
  InitiateConnect(service);

  EXPECT_FALSE(GetPendingService() == NULL);
  EXPECT_TRUE(service->IsConnecting());
  EXPECT_CALL(supplicant_interface_proxy, Disconnect());
  InitiateDisconnect(service);
  EXPECT_FALSE(service->IsConnecting());

  EXPECT_TRUE(GetPendingService() == NULL);
}

TEST_F(WiFiMainTest, DisconnectPendingServiceWithCurrent) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid1", "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  WiFiService *service0(GetServices()[0].get());
  WiFiService *service1(GetServices()[1].get());

  InitiateConnect(service0);
  ReportCurrentBSSChanged("bss0");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  InitiateConnect(service1);

  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(service1, GetPendingService());
  EXPECT_CALL(supplicant_interface_proxy, Disconnect());
  InitiateDisconnect(service1);

  // |current_service_| will be unchanged until supplicant signals
  // that CurrentBSS has changed.
  EXPECT_EQ(service0, GetCurrentService());
  // |pending_service_| is updated immediately.
  EXPECT_TRUE(GetPendingService() == NULL);
  EXPECT_TRUE(GetPendingTimeout().IsCancelled());
}

TEST_F(WiFiMainTest, DisconnectCurrentService) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  DBus::Path fake_path("/fake/path");
  WiFiService *service(SetupConnectedService(fake_path));
  EXPECT_CALL(supplicant_interface_proxy, Disconnect());
  InitiateDisconnect(service);

  // |current_service_| should not change until supplicant reports
  // a BSS change.
  EXPECT_EQ(service, GetCurrentService());

  // Expect that the entry associated with this network will be disabled.
  MockSupplicantNetworkProxy *network_proxy = CreateSupplicantNetworkProxy();
  EXPECT_CALL(*proxy_factory(), CreateSupplicantNetworkProxy(
      fake_path, wpa_supplicant::kDBusAddr))
      .WillOnce(Return(network_proxy));
  EXPECT_CALL(*network_proxy, SetEnabled(false));
  EXPECT_CALL(supplicant_interface_proxy, RemoveNetwork(fake_path)).Times(0);
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, DisconnectCurrentServiceWithErrors) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  DBus::Path fake_path("/fake/path");
  WiFiService *service(SetupConnectedService(fake_path));
  EXPECT_CALL(supplicant_interface_proxy, Disconnect())
      .WillOnce(InvokeWithoutArgs(this, (&WiFiMainTest::ThrowDBusError)));
  EXPECT_CALL(supplicant_interface_proxy, RemoveNetwork(fake_path)).Times(1);
  InitiateDisconnect(service);

  // We may sometimes fail to disconnect via supplicant, and we patch up some
  // state when this happens.
  EXPECT_EQ(NULL, GetCurrentService().get());
  EXPECT_EQ(NULL, wifi()->selected_service().get());
}

TEST_F(WiFiMainTest, DisconnectCurrentServiceWithPending) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportBSS("bss1", "ssid1", "00:00:00:00:00:01", 0, 0, kNetworkModeAdHoc);
  WiFiService *service0(GetServices()[0].get());
  WiFiService *service1(GetServices()[1].get());

  InitiateConnect(service0);
  ReportCurrentBSSChanged("bss0");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  InitiateConnect(service1);

  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(service1, GetPendingService());
  EXPECT_CALL(supplicant_interface_proxy, Disconnect())
      .Times(0);
  InitiateDisconnect(service0);

  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(service1, GetPendingService());
  EXPECT_FALSE(GetPendingTimeout().IsCancelled());
}

TEST_F(WiFiMainTest, TimeoutPendingService) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  const base::CancelableClosure &pending_timeout = GetPendingTimeout();
  EXPECT_TRUE(pending_timeout.IsCancelled());

  InSequence seq;
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  EXPECT_CALL(*service, SetState(Service::kStateAssociating));
  InitiateConnect(service);
  EXPECT_FALSE(pending_timeout.IsCancelled());
  EXPECT_EQ(service, GetPendingService());

  {
    InSequence seq;
    EXPECT_CALL(*service, SetState(Service::kStateIdle));
    EXPECT_CALL(*service, SetFailure(Service::kFailureOutOfRange));
    pending_timeout.callback().Run();
  }
  EXPECT_EQ(NULL, GetPendingService().get());

  // Verify expectations now, because WiFi may report other state changes
  // when WiFi is Stop()-ed (during TearDown()).
  Mock::VerifyAndClearExpectations(service.get());
}

TEST_F(WiFiMainTest, DisconnectInvalidService) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  WiFiService *service(GetServices().begin()->get());
  EXPECT_CALL(supplicant_interface_proxy, Disconnect())
      .Times(0);
  InitiateDisconnect(service);
}

TEST_F(WiFiMainTest, DisconnectCurrentServiceFailure) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  DBus::Path fake_path("/fake/path");
  WiFiService *service(SetupConnectedService(fake_path));
  EXPECT_CALL(supplicant_interface_proxy, Disconnect())
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.NotConnected",
              "test threw fi.w1.wpa_supplicant1.NotConnected")));
  EXPECT_CALL(supplicant_interface_proxy, RemoveNetwork(fake_path));
  InitiateDisconnect(service);

  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, Stop) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();

  EXPECT_CALL(*manager(), DeregisterService(_));
  StopWiFi();
  EXPECT_TRUE(GetScanTimer().IsCancelled());
  EXPECT_FALSE(wifi()->weak_ptr_factory_.HasWeakPtrs());
}

TEST_F(WiFiMainTest, StopWhileConnected) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  WiFiService *service(SetupConnectedService(DBus::Path()));
  EXPECT_CALL(*manager(), DeregisterService(ServiceRefPtr(service)))
      .WillOnce(Invoke(this, &WiFiObjectTest::UnloadService));
  EXPECT_CALL(supplicant_interface_proxy, Disconnect());
  StopWiFi();
  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, ReconnectTimer) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  WiFiService *service(SetupConnectedService(DBus::Path()));
  service->SetState(Service::kStateConnected);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(wpa_supplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(wpa_supplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  ReportCurrentBSSChanged(kBSSName);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(wpa_supplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  EXPECT_CALL(supplicant_interface_proxy, Disconnect());
  GetReconnectTimeoutCallback().callback().Run();
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy_);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
}

TEST_F(WiFiMainTest, GetWifiServiceOpen) {
  Error e;
  GetOpenService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged, &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceOpenNoSSID) {
  Error e;
  GetOpenService(flimflam::kTypeWifi, NULL, flimflam::kModeManaged, &e);
  EXPECT_EQ(Error::kInvalidArguments, e.type());
  EXPECT_EQ("must specify SSID", e.message());
}

TEST_F(WiFiMainTest, GetWifiServiceOpenLongSSID) {
  Error e;
  GetOpenService(
      flimflam::kTypeWifi, "123456789012345678901234567890123",
      flimflam::kModeManaged, &e);
  EXPECT_EQ(Error::kInvalidNetworkName, e.type());
  EXPECT_EQ("SSID is too long", e.message());
}

TEST_F(WiFiMainTest, GetWifiServiceOpenShortSSID) {
  Error e;
  GetOpenService(flimflam::kTypeWifi, "", flimflam::kModeManaged, &e);
  EXPECT_EQ(Error::kInvalidNetworkName, e.type());
  EXPECT_EQ("SSID is too short", e.message());
}

TEST_F(WiFiMainTest, GetWifiServiceOpenBadMode) {
  Error e;
  GetOpenService(flimflam::kTypeWifi, "an_ssid", "ad-hoc", &e);
  EXPECT_EQ(Error::kNotSupported, e.type());
  EXPECT_EQ("service mode is unsupported", e.message());
}

TEST_F(WiFiMainTest, GetWifiServiceOpenNoMode) {
  Error e;
  GetOpenService(flimflam::kTypeWifi, "an_ssid", NULL, &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceRSN) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityRsn, "secure password", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceRSNNoPassword) {
  // When configuring hidden networks, Chrome expects to be able to
  // GetService w/o a password, and supply the password with
  // SetProperty afterwards.
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityRsn, NULL, &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceBadSecurity) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged, "rot-13",
             NULL, &e);
  EXPECT_EQ(Error::kNotSupported, e.type());
  EXPECT_EQ("security mode is unsupported", e.message());
}

TEST_F(WiFiMainTest, GetWifiServiceWEPNoPassword) {
  // When configuring hidden networks, Chrome expects to be able to
  // GetService w/o a password, and supply the password with
  // SetProperty afterwards.
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, NULL, &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEPEmptyPassword) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "", &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40ASCII) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "abcde", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP104ASCII) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "abcdefghijklm", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40ASCIIWithKeyIndex) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0:abcdefghijklm", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40Hex) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0102030405", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40HexBadPassphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "O102030405", &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40HexWithKeyIndexBadPassphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "1:O102030405", &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40HexWithKeyIndexAndBaseBadPassphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "1:0xO102030405", &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP40HexWithBaseBadPassphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0xO102030405", &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP104Hex) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0102030405060708090a0b0c0d", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP104HexUppercase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0102030405060708090A0B0C0D", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP104HexWithKeyIndex) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0:0102030405060708090a0b0c0d", &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_F(WiFiMainTest, GetWifiServiceWEP104HexWithKeyIndexAndBase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWep, "0:0x0102030405060708090a0b0c0d", &e);
  EXPECT_TRUE(e.IsSuccess());
}

class WiFiGetServiceSuccessTest : public WiFiMainTest {};
class WiFiGetServiceFailureTest : public WiFiMainTest {};

TEST_P(WiFiGetServiceSuccessTest, Passphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWpa, GetParam().c_str(), &e);
  EXPECT_TRUE(e.IsSuccess());
}

TEST_P(WiFiGetServiceFailureTest, Passphrase) {
  Error e;
  GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
             flimflam::kSecurityWpa, GetParam().c_str(), &e);
  EXPECT_EQ(Error::kInvalidPassphrase, e.type());
}

INSTANTIATE_TEST_CASE_P(
    WiFiGetServiceSuccessTestInstance,
    WiFiGetServiceSuccessTest,
    Values(
        string(IEEE_80211::kWPAAsciiMinLen, 'Z'),
        string(IEEE_80211::kWPAAsciiMaxLen, 'Z'),
        // subtle: invalid length for hex key, but valid as ascii passphrase
        string(IEEE_80211::kWPAHexLen-1, '1'),
        string(IEEE_80211::kWPAHexLen, '1')));

INSTANTIATE_TEST_CASE_P(
    WiFiGetServiceFailureTestInstance,
    WiFiGetServiceFailureTest,
    Values(
        string(IEEE_80211::kWPAAsciiMinLen-1, 'Z'),
        string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z'),
        string(IEEE_80211::kWPAHexLen+1, '1')));

TEST_F(WiFiMainTest, FindServiceWEP) {
  const string ssid("an_ssid");
  {
    Error e;
    GetService(flimflam::kTypeWifi, ssid.c_str(), flimflam::kModeManaged,
               flimflam::kSecurityWep, "abcde", &e);
    EXPECT_TRUE(e.IsSuccess());
  }
  vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end());

  EXPECT_TRUE(FindService(ssid_bytes, flimflam::kModeManaged,
                          flimflam::kSecurityWep).get());
  EXPECT_FALSE(FindService(ssid_bytes, flimflam::kModeManaged,
                           flimflam::kSecurityWpa).get());
}

TEST_F(WiFiMainTest, FindServiceWPA) {
  const string ssid("an_ssid");
  {
    Error e;
    GetService(flimflam::kTypeWifi, ssid.c_str(), flimflam::kModeManaged,
               flimflam::kSecurityRsn, "abcdefgh", &e);
    EXPECT_TRUE(e.IsSuccess());
  }
  vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end());
  WiFiServiceRefPtr wpa_service(FindService(ssid_bytes, flimflam::kModeManaged,
                                            flimflam::kSecurityWpa));
  EXPECT_TRUE(wpa_service.get());
  WiFiServiceRefPtr rsn_service(FindService(ssid_bytes, flimflam::kModeManaged,
                                            flimflam::kSecurityRsn));
  EXPECT_TRUE(rsn_service.get());
  EXPECT_EQ(wpa_service.get(), rsn_service.get());
  WiFiServiceRefPtr psk_service(FindService(ssid_bytes, flimflam::kModeManaged,
                                            flimflam::kSecurityPsk));
  EXPECT_EQ(wpa_service.get(), psk_service.get());
  // Indirectly test FindService by doing a GetService on something that
  // already exists.
  {
    Error e;
    WiFiServiceRefPtr wpa_service2(
        GetServiceInner(flimflam::kTypeWifi, ssid.c_str(),
                        flimflam::kModeManaged, flimflam::kSecurityWpa,
                        "abcdefgh", false, &e));
    EXPECT_TRUE(e.IsSuccess());
    EXPECT_EQ(wpa_service.get(), wpa_service2.get());
  }
}

TEST_F(WiFiMainTest, GetServiceWithGUID) {
  // Perform a GetService and also configure properties in the base Service
  // class using Service::Configure().
  KeyValueStore args;
  args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
  args.SetString(flimflam::kSSIDProperty, "ssid");
  args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityNone);
  const string kGUID = "aguid";  // Stored as a registered Service property.
  args.SetString(flimflam::kGuidProperty, kGUID);

  Error e;
  WiFiServiceRefPtr service = GetServiceWithKeyValues(args, &e);
  EXPECT_TRUE(e.IsSuccess());
  // Assert that before Configure is called on the service, the GUID property
  // is not set.
  EXPECT_EQ("", service->guid());

  service->Configure(args, &e);
  EXPECT_TRUE(e.IsSuccess());
  EXPECT_EQ(kGUID, service->guid());
}

MATCHER_P(HasHiddenSSID, ssid, "") {
  map<string, DBus::Variant>::const_iterator it =
      arg.find(wpa_supplicant::kPropertyScanSSIDs);
  if (it == arg.end()) {
    return false;
  }

  const DBus::Variant &ssids_variant = it->second;
  EXPECT_TRUE(DBusAdaptor::IsByteArrays(ssids_variant.signature()));
  const ByteArrays &ssids = it->second.operator ByteArrays();
  // A valid Scan containing a single hidden SSID should contain
  // two SSID entries: one containing the SSID we are looking for,
  // and an empty entry, signifying that we also want to do a
  // broadcast probe request for all non-hidden APs as well.
  return ssids.size() == 2 &&
      string(ssids[0].begin(), ssids[0].end()) == ssid &&
      ssids[1].empty();
}

TEST_F(WiFiMainTest, ScanHidden) {
  EXPECT_CALL(*supplicant_process_proxy_, CreateInterface(_));
  EXPECT_CALL(*supplicant_process_proxy_, GetInterface(_))
      .Times(AnyNumber())
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.InterfaceUnknown",
              "test threw fi.w1.wpa_supplicant1.InterfaceUnknown")));
  scoped_refptr<MockProfile> profile(
      new NiceMock<MockProfile>(control_interface(), manager(), ""));
  {
    // Create a hidden service with an associated profile.
    Error e;
    WiFiServiceRefPtr service =
        GetServiceInner(flimflam::kTypeWifi, "ssid0", flimflam::kModeManaged,
                        NULL, NULL, true, &e);
    EXPECT_TRUE(e.IsSuccess());
    EXPECT_TRUE(service->hidden_ssid());
    service->set_profile(profile);
  }
  {
    // Create a hidden service without an associated profile.
    Error e;
    WiFiServiceRefPtr service =
        GetServiceInner(flimflam::kTypeWifi, "ssid1", flimflam::kModeManaged,
                        NULL, NULL, true, &e);
    EXPECT_TRUE(e.IsSuccess());
    EXPECT_TRUE(service->hidden_ssid());
  }
  {
    // Create a non-hidden service with an associated profile.
    Error e;
    WiFiServiceRefPtr service =
        GetServiceInner(flimflam::kTypeWifi, "ssid2", flimflam::kModeManaged,
                        NULL, NULL, false, &e);
    EXPECT_TRUE(e.IsSuccess());
    EXPECT_FALSE(service->hidden_ssid());
    service->set_profile(profile);
  }
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(HasHiddenSSID("ssid0")));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ScanWiFiDisabledAfterResume) {
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, EndsWith(
      "Ignoring scan request while device is not enabled."))).Times(1);
  EXPECT_CALL(*supplicant_interface_proxy_, Scan(_)).Times(0);
  StartWiFi();
  StopWiFi();
  // A scan is queued when WiFi resumes.
  OnAfterResume();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, InitialSupplicantState) {
  EXPECT_EQ(WiFi::kInterfaceStateUnknown, GetSupplicantState());
}

TEST_F(WiFiMainTest, StateChangeNoService) {
  // State change should succeed even if there is no pending Service.
  ReportStateChanged(wpa_supplicant::kInterfaceStateScanning);
  EXPECT_EQ(wpa_supplicant::kInterfaceStateScanning, GetSupplicantState());
}

TEST_F(WiFiMainTest, StateChangeWithService) {
  // Forward transition should trigger a Service state change.
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  InitiateConnect(service);
  EXPECT_CALL(*service.get(), SetState(Service::kStateAssociating));
  ReportStateChanged(wpa_supplicant::kInterfaceStateAssociated);
  // Verify expectations now, because WiFi may report other state changes
  // when WiFi is Stop()-ed (during TearDown()).
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_CALL(*service.get(), SetState(_)).Times(AnyNumber());
}

TEST_F(WiFiMainTest, StateChangeBackwardsWithService) {
  // Some backwards transitions should not trigger a Service state change.
  // Supplicant state should still be updated, however.
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  EXPECT_CALL(*service.get(), SetState(Service::kStateAssociating));
  EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
  InitiateConnect(service);
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  ReportStateChanged(wpa_supplicant::kInterfaceStateAuthenticating);
  EXPECT_EQ(wpa_supplicant::kInterfaceStateAuthenticating,
            GetSupplicantState());
  // Verify expectations now, because WiFi may report other state changes
  // when WiFi is Stop()-ed (during TearDown()).
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_CALL(*service.get(), SetState(_)).Times(AnyNumber());
}

TEST_F(WiFiMainTest, ConnectToServiceWithoutRecentIssues) {
  MockSupplicantProcessProxy *process_proxy = supplicant_process_proxy_.get();
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  EXPECT_CALL(*process_proxy, GetDebugLevel()).Times(0);
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  EXPECT_CALL(*service.get(), HasRecentConnectionIssues())
      .WillOnce(Return(false));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, ConnectToServiceWithRecentIssues) {
  // Turn of WiFi debugging, so the only reason we will turn on supplicant
  // debugging will be to debug a problematic connection.
  ScopeLogger::GetInstance()->EnableScopesByName("-wifi");

  MockSupplicantProcessProxy *process_proxy = supplicant_process_proxy_.get();
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelInfo));
  EXPECT_CALL(*process_proxy, SetDebugLevel(wpa_supplicant::kDebugLevelDebug))
      .Times(1);
  EXPECT_CALL(*service.get(), HasRecentConnectionIssues())
      .WillOnce(Return(true));
  InitiateConnect(service);
  Mock::VerifyAndClearExpectations(process_proxy);

  SetPendingService(NULL);
  SetCurrentService(service);

  // When we disconnect from the troubled service, we should reduce the
  // level of supplciant debugging.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelDebug));
  EXPECT_CALL(*process_proxy, SetDebugLevel(wpa_supplicant::kDebugLevelInfo))
      .Times(1);
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
}

TEST_F(WiFiMainTest, LoadHiddenServicesFailWithNoGroups) {
  StrictMock<MockStore> storage;
  EXPECT_CALL(storage, GetGroupsWithKey(flimflam::kWifiHiddenSsid))
      .WillOnce(Return(set<string>()));
  EXPECT_FALSE(LoadHiddenServices(&storage));
}

TEST_F(WiFiMainTest, LoadHiddenServicesFailWithMissingHidden) {
  string id;
  StrictMock<MockStore> storage;
  SetupHiddenStorage(&storage, "an_ssid", &id);
  // Missing "Hidden" property.
  EXPECT_CALL(storage, GetBool(StrEq(id), flimflam::kWifiHiddenSsid, _))
      .WillOnce(Return(false));
  EXPECT_FALSE(LoadHiddenServices(&storage));
}

TEST_F(WiFiMainTest, LoadHiddenServicesFailWithFalseHidden) {
  string id;
  StrictMock<MockStore> storage;
  SetupHiddenStorage(&storage, "an_ssid", &id);
  // "Hidden" property set to "false".
  EXPECT_CALL(storage, GetBool(StrEq(id), flimflam::kWifiHiddenSsid, _))
      .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(false)));
  EXPECT_FALSE(LoadHiddenServices(&storage));
}

TEST_F(WiFiMainTest, LoadHiddenServicesFailWithMissingSSID) {
  string id;
  StrictMock<MockStore> storage;
  SetupHiddenStorage(&storage, "an_ssid", &id);
  // Missing "SSID" property.
  EXPECT_CALL(storage, GetString(StrEq(id), flimflam::kSSIDProperty, _))
      .WillOnce(Return(false));
  EXPECT_FALSE(LoadHiddenServices(&storage));
}


TEST_F(WiFiMainTest, LoadHiddenServicesFailWithFoundService) {
  StrictMock<MockStore> storage;
  string id;
  SetupHiddenStorage(&storage, "an_ssid", &id);
  Error e;
  GetOpenService(flimflam::kTypeWifi, "an_ssid", NULL, &e);
  ASSERT_TRUE(e.IsSuccess());
  EXPECT_FALSE(LoadHiddenServices(&storage));
}

TEST_F(WiFiMainTest, LoadHiddenServicesSuccess) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  StrictMock<MockStore> storage;
  string ssid("an_ssid");
  string id;
  SetupHiddenStorage(&storage, ssid, &id);
  EXPECT_TRUE(LoadHiddenServices(&storage));
  vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end());
  EXPECT_TRUE(FindService(ssid_bytes, flimflam::kModeManaged,
                          flimflam::kSecurityNone).get());
}

TEST_F(WiFiMainTest, CurrentBSSChangeConnectedToDisconnected) {
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);

  // Note that the BSS handle used in this test ("an_ap") is not
  // intended to reflect the format used by supplicant. It's just
  // convenient for testing.

  StartWiFi();
  ReportBSS("an_ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);
  EXPECT_EQ(service, GetPendingService().get());

  ReportCurrentBSSChanged("an_ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_EQ(Service::kStateConfiguring, service->state());
  EXPECT_EQ(service, GetCurrentService().get());
  EXPECT_EQ(NULL, GetPendingService().get());

  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
  EXPECT_EQ(Service::kStateIdle, service->state());
  EXPECT_TRUE(service->IsFailed());
  EXPECT_EQ(NULL, GetCurrentService().get());
  EXPECT_EQ(NULL, GetPendingService().get());
}

TEST_F(WiFiMainTest, CurrentBSSChangeConnectedToConnectedNewService) {
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  WiFiEndpointRefPtr ap1 = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiEndpointRefPtr ap2 = MakeEndpoint("another_ssid", "01:02:03:04:05:06");
  WiFiServiceRefPtr service1 = CreateServiceForEndpoint(*ap1);
  WiFiServiceRefPtr service2 = CreateServiceForEndpoint(*ap2);

  // Note that the BSS handles used in this test ("ap1", "ap2") are
  // not intended to reflect the format used by supplicant. They're
  // just convenient for testing.

  StartWiFi();
  ReportBSS("ap1", ap1->ssid_string(), ap1->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  ReportBSS("ap2", ap2->ssid_string(), ap2->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service1);
  ReportCurrentBSSChanged("ap1");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_EQ(service1.get(), GetCurrentService().get());

  // Note that we deliberately omit intermediate supplicant states
  // (e.g. kInterfaceStateAssociating), on the theory that they are
  // unreliable. Specifically, they may be quashed if the association
  // completes before supplicant flushes its changed properties.
  ReportCurrentBSSChanged("ap2");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_EQ(service2.get(), GetCurrentService().get());
  EXPECT_EQ(Service::kStateIdle, service1->state());
  EXPECT_EQ(Service::kStateConfiguring, service2->state());
}

TEST_F(WiFiMainTest, CurrentBSSChangeDisconnectedToConnected) {
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);

  // Note that the BSS handle used in this test ("an_ap") is not
  // intended to reflect the format used by supplicant. It's just
  // convenient for testing.

  StartWiFi();
  ReportBSS("an_ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);
  ReportCurrentBSSChanged("an_ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_EQ(service.get(), GetCurrentService().get());
  EXPECT_EQ(Service::kStateConfiguring, service->state());
}

TEST_F(WiFiMainTest, CurrentBSSChangedUpdateServiceEndpoint) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());

  const uint16 frequency1 = 2412;
  const uint16 frequency2 = 2442;
  StartWiFi();
  ReportBSS("bss1", "ssid1", "00:00:00:00:00:01", 1, frequency1,
            kNetworkModeInfrastructure);
  ReportBSS("bss2", "ssid1", "00:00:00:00:00:02", 1, frequency2,
            kNetworkModeInfrastructure);
  EXPECT_EQ(1, GetServices().size());
  WiFiService *service(GetServices()[0].get());
  InitiateConnect(service);
  ReportCurrentBSSChanged("bss1");
  EXPECT_EQ(frequency1, service->frequency_);
  EXPECT_EQ("00:00:00:00:00:01", service->bssid_);
  ReportCurrentBSSChanged("bss2");
  EXPECT_EQ(frequency2, service->frequency_);
  EXPECT_EQ("00:00:00:00:00:02", service->bssid_);
}

TEST_F(WiFiMainTest, ConfiguredServiceRegistration) {
  Error e;
  EXPECT_CALL(*manager(), RegisterService(_))
      .Times(0);
  EXPECT_CALL(*manager(), HasService(_))
      .WillOnce(Return(false));
  GetOpenService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged, &e);
  EXPECT_CALL(*manager(), RegisterService(_));
  ReportBSS("ap0", "an_ssid", "00:00:00:00:00:00", 0, 0,
            kNetworkModeInfrastructure);
}

TEST_F(WiFiMainTest, NewConnectPreemptsPending) {
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  WiFiEndpointRefPtr ap1 = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiEndpointRefPtr ap2 = MakeEndpoint("another_ssid", "01:02:03:04:05:06");
  WiFiServiceRefPtr service1 = CreateServiceForEndpoint(*ap1);
  WiFiServiceRefPtr service2 = CreateServiceForEndpoint(*ap2);

  StartWiFi();
  ReportBSS("ap1", ap1->ssid_string(), ap1->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  ReportBSS("ap2", ap2->ssid_string(), ap2->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service1);
  EXPECT_EQ(service1.get(), GetPendingService().get());

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(_));
  InitiateConnect(service2);
  EXPECT_EQ(service2.get(), GetPendingService().get());
}

TEST_F(WiFiMainTest, IsIdle) {
  StartWiFi();
  EXPECT_TRUE(wifi()->IsIdle());

  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
  Error error;
  service->AddEndpoint(ap);
  service->AutoConnect();
  EXPECT_FALSE(wifi()->IsIdle());
}

MATCHER_P(WiFiAddedArgs, bgscan, "") {
  return ContainsKey(arg, wpa_supplicant::kNetworkPropertyScanSSID) &&
      ContainsKey(arg, wpa_supplicant::kNetworkPropertyBgscan) == bgscan;
}

TEST_F(WiFiMainTest, AddNetworkArgs) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  WiFiService *service(GetServices().begin()->get());
  EXPECT_CALL(supplicant_interface_proxy, AddNetwork(WiFiAddedArgs(true)));
  EXPECT_TRUE(SetBgscanMethod(wpa_supplicant::kNetworkBgscanMethodSimple));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, AddNetworkArgsNoBgscan) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  WiFiService *service(GetServices().begin()->get());
  EXPECT_CALL(supplicant_interface_proxy, AddNetwork(WiFiAddedArgs(false)));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, AppendBgscan) {
  StartWiFi();
  WiFiEndpointRefPtr ap1 = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap1);
  service->AddEndpoint(ap1);
  EXPECT_EQ(1, service->GetEndpointCount());
  {
    // 1 endpoint, default bgscan method -- background scan disabled.
    std::map<std::string, DBus::Variant> params;
    AppendBgscan(service.get(), &params);
    EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyBgscan));
  }
  WiFiEndpointRefPtr ap2 = MakeEndpoint("an_ssid", "01:02:03:04:05:06");
  service->AddEndpoint(ap2);
  EXPECT_EQ(2, service->GetEndpointCount());
  {
    // 2 endpoints, default bgscan method -- background scan frequency reduced.
    map<string, DBus::Variant> params;
    AppendBgscan(service.get(), &params);
    string config_string;
    EXPECT_TRUE(
        DBusProperties::GetString(params,
                                  wpa_supplicant::kNetworkPropertyBgscan,
                                  &config_string));
    vector<string> elements;
    base::SplitString(config_string, ':', &elements);
    ASSERT_EQ(4, elements.size());
    EXPECT_EQ(WiFi::kDefaultBgscanMethod, elements[0]);
    EXPECT_EQ(StringPrintf("%d", WiFi::kBackgroundScanIntervalSeconds),
              elements[3]);
  }
  {
    // Explicit bgscan method -- regular background scan frequency.
    EXPECT_TRUE(SetBgscanMethod(wpa_supplicant::kNetworkBgscanMethodSimple));
    std::map<std::string, DBus::Variant> params;
    AppendBgscan(service.get(), &params);
    string config_string;
    EXPECT_TRUE(
        DBusProperties::GetString(params,
                                  wpa_supplicant::kNetworkPropertyBgscan,
                                  &config_string));
    vector<string> elements;
    base::SplitString(config_string, ':', &elements);
    ASSERT_EQ(4, elements.size());
    EXPECT_EQ(StringPrintf("%d", WiFi::kDefaultScanIntervalSeconds),
              elements[3]);
  }
  {
    // No scan method, simply returns without appending properties
    EXPECT_TRUE(SetBgscanMethod(wpa_supplicant::kNetworkBgscanMethodNone));
    std::map<std::string, DBus::Variant> params;
    AppendBgscan(service.get(), &params);
    string config_string;
    EXPECT_FALSE(
        DBusProperties::GetString(params,
                                  wpa_supplicant::kNetworkPropertyBgscan,
                                  &config_string));
  }
}

TEST_F(WiFiMainTest, StateAndIPIgnoreLinkEvent) {
  StartWiFi();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  InitiateConnect(service);
  EXPECT_CALL(*service.get(), SetState(_)).Times(0);
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(0);
  ReportLinkUp();

  // Verify expectations now, because WiFi may cause |service| state
  // changes during TearDown().
  Mock::VerifyAndClearExpectations(service);
  EXPECT_CALL(*service.get(), SetState(_)).Times(AnyNumber());
}

TEST_F(WiFiMainTest, SupplicantCompleted) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(supplicant_interface_proxy, EnableHighBitrates()).Times(0);
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);

  StartWiFi();
  ReportBSS("ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);

  EXPECT_CALL(*dhcp_config_.get(), RequestIP());
  ReportCurrentBSSChanged("ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  EXPECT_EQ(Service::kStateConfiguring, service->state());
}

TEST_F(WiFiMainTest, SupplicantCompletedAlreadyConnected) {
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;
  EXPECT_CALL(*dhcp_config_.get(), RequestIP());
  EXPECT_CALL(*manager(), UpdateService(_)).Times(AnyNumber());
  EXPECT_CALL(*device_info(), FlushAddresses(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), device_info()).Times(AnyNumber());
  EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
  EXPECT_CALL(*manager(), HasService(_)).Times(AnyNumber());
  EXPECT_CALL(*manager(), IsPortalDetectionEnabled(_)).Times(AnyNumber());
  EXPECT_CALL(supplicant_interface_proxy, EnableHighBitrates()).Times(0);
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);

  StartWiFi();
  ReportBSS("ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);
  ReportCurrentBSSChanged("ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  Mock::VerifyAndClearExpectations(dhcp_config_.get());
  EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(0);
  // Simulate a rekeying event from the AP.  These show as transitions from
  // completed->completed from wpa_supplicant.
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  // When we get an IP, WiFi should enable high bitrates on the interface again.
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);
  EXPECT_CALL(supplicant_interface_proxy, EnableHighBitrates()).Times(1);
  ReportIPConfigComplete();
  // Similarly, rekeying events after we have an IP don't trigger L3
  // configuration.  However, we treat all transitions to completed as potential
  // reassociations, so we will reenable high rates again here.
  Mock::VerifyAndClearExpectations(&supplicant_interface_proxy);
  EXPECT_CALL(supplicant_interface_proxy, EnableHighBitrates()).Times(1);
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
}

TEST_F(WiFiMainTest, BSSAddedCreatesBSSProxy) {
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());
  // TODO(quiche): Consider using a factory for WiFiEndpoints, so that
  // we can test the interaction between WiFi and WiFiEndpoint. (Right
  // now, we're testing across multiple layers.)
  EXPECT_CALL(*supplicant_bss_proxy_, Die()).Times(AnyNumber());
  EXPECT_CALL(*proxy_factory(), CreateSupplicantBSSProxy(_, _, _));
  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
}

TEST_F(WiFiMainTest, BSSRemovedDestroysBSSProxy) {
  // TODO(quiche): As for BSSAddedCreatesBSSProxy, consider using a
  // factory for WiFiEndpoints.
  EXPECT_CALL(*manager(), RegisterService(_)).Times(AnyNumber());

  // Get the pointer before we transfer ownership.
  MockSupplicantBSSProxy *proxy = supplicant_bss_proxy_.get();
  EXPECT_CALL(*proxy, Die());
  StartWiFi();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  RemoveBSS("bss0");
  // Check this now, to make sure RemoveBSS killed the proxy (rather
  // than TearDown).
  Mock::VerifyAndClearExpectations(proxy);
}

TEST_F(WiFiMainTest, FlushBSSOnResume) {
  const struct timeval resume_time = {1, 0};
  const struct timeval scan_done_time = {6, 0};
  MockSupplicantInterfaceProxy &supplicant_interface_proxy =
      *supplicant_interface_proxy_;

  StartWiFi();

  EXPECT_CALL(time_, GetTimeMonotonic(_))
      .WillOnce(DoAll(SetArgumentPointee<0>(resume_time), Return(0)))
      .WillOnce(DoAll(SetArgumentPointee<0>(scan_done_time), Return(0)));
  EXPECT_CALL(supplicant_interface_proxy,
              FlushBSS(WiFi::kMaxBSSResumeAgeSeconds + 5));
  OnAfterResume();
  ReportScanDone();
}

TEST_F(WiFiMainTest, ScanTimerIdle) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportScanDone();
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
  FireScanTimer();
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());  // Automatically re-armed.
}

TEST_F(WiFiMainTest, ScanTimerScanning) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

  // Should not call Scan, since we're already scanning.
  // (Scanning is triggered by StartWiFi.)
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  FireScanTimer();
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());  // Automatically re-armed.
}

TEST_F(WiFiMainTest, ScanTimerConnecting) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportBSS("bss0", "ssid0", "00:00:00:00:00:00", 0, 0, kNetworkModeAdHoc);
  ReportScanDone();
  WiFiService *service(GetServices().begin()->get());
  InitiateConnect(service);
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  FireScanTimer();
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());  // Automatically re-armed.
}

TEST_F(WiFiMainTest, ScanTimerReconfigured) {
  StartWiFi();
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

  SetScanInterval(1);
  EXPECT_FALSE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ScanTimerResetOnScanDone) {
  StartWiFi();
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

  ReportScanDone();
  EXPECT_FALSE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ScanTimerStopOnZeroInterval) {
  StartWiFi();
  EXPECT_FALSE(GetScanTimer().IsCancelled());

  SetScanInterval(0);
  EXPECT_TRUE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ScanOnDisconnectWithHidden) {
  Error e;
  scoped_refptr<MockProfile> profile(
      new NiceMock<MockProfile>(control_interface(), manager(), ""));
  WiFiServiceRefPtr hidden_service =
      GetServiceInner(flimflam::kTypeWifi, "hidden_ssid",
                      flimflam::kModeManaged, NULL, NULL, true, &e);
  hidden_service->set_profile(profile);

  StartWiFi();
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
  ReportBSS("an_ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);
  ReportCurrentBSSChanged("an_ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  dispatcher_.DispatchPendingEvents();

  EXPECT_CALL(*GetSupplicantInterfaceProxy(),
              Scan(HasHiddenSSID("hidden_ssid")));
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, NoScanOnDisconnectWithoutHidden) {
  StartWiFi();
  WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
  WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
  ReportBSS("an_ap", ap->ssid_string(), ap->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  InitiateConnect(service);
  ReportCurrentBSSChanged("an_ap");
  ReportStateChanged(wpa_supplicant::kInterfaceStateCompleted);
  dispatcher_.DispatchPendingEvents();

  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, LinkMonitorFailure) {
  StartWiFi();
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  MockLinkMonitor *link_monitor = new StrictMock<MockLinkMonitor>();
  SetLinkMonitor(link_monitor);
  EXPECT_CALL(*link_monitor, IsGatewayFound())
      .WillOnce(Return(false))
      .WillRepeatedly(Return(true));
  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
                       EndsWith("gateway was never found."))).Times(1);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Reassociate()).Times(0);
  OnLinkMonitorFailure();
  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
                       EndsWith("Called Reassociate()."))).Times(1);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Reassociate()).Times(1);
  OnLinkMonitorFailure();
  OnSupplicantVanish();
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith("Cannot reassociate."))).Times(1);
  OnLinkMonitorFailure();
}

TEST_F(WiFiMainTest, SuspectCredentialsOpen) {
  Error e;
  WiFiServiceRefPtr service = GetOpenService(
      flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged, &e);
  ReportStateChanged(wpa_supplicant::kInterfaceState4WayHandshake);
  EXPECT_FALSE(service->has_ever_connected());
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsWPANeverConnected) {
  Error e;
  WiFiServiceRefPtr service =
      GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
                 flimflam::kSecurityWpa, "abcdefgh", &e);
  ReportStateChanged(wpa_supplicant::kInterfaceState4WayHandshake);
  EXPECT_FALSE(service->has_ever_connected());
  Service::ConnectFailure failure;
  EXPECT_TRUE(SuspectCredentials(*service, &failure));
  EXPECT_EQ(Service::kFailureBadPassphrase, failure);
}

TEST_F(WiFiMainTest, SuspectCredentialsWPAPreviouslyConnected) {
  Error e;
  WiFiServiceRefPtr service =
      GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
                 flimflam::kSecurityWpa, "abcdefgh", &e);
  ReportStateChanged(wpa_supplicant::kInterfaceState4WayHandshake);
  service->has_ever_connected_ = true;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsEAPInProgress) {
  Error e;
  WiFiServiceRefPtr service =
      GetService(flimflam::kTypeWifi, "an_ssid", flimflam::kModeManaged,
                 flimflam::kSecurity8021x, "abcdefgh", &e);
  SetCurrentService(service);
  service->has_ever_connected_ = false;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
  ReportEAPEvent(wpa_supplicant::kEAPStatusStarted, "");
  service->has_ever_connected_ = true;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
  service->has_ever_connected_ = false;
  Service::ConnectFailure failure;
  EXPECT_TRUE(SuspectCredentials(*service, &failure));
  EXPECT_EQ(Service::kFailureEAPAuthentication, failure);
  ReportEAPEvent(wpa_supplicant::kEAPStatusCompletion,
                 wpa_supplicant::kEAPParameterSuccess);
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsYieldFailureWPA) {
  ScopedMockLog log;
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityWpa);
  SetPendingService(service);
  ReportStateChanged(wpa_supplicant::kInterfaceState4WayHandshake);
  EXPECT_FALSE(service->has_ever_connected());

  EXPECT_CALL(*service, SetFailure(Service::kFailureBadPassphrase));
  EXPECT_CALL(*service, SetFailureSilent(_)).Times(0);
  EXPECT_CALL(*service, SetState(_)).Times(0);
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith(flimflam::kErrorBadPassphrase)));
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
}

TEST_F(WiFiMainTest, SuspectCredentialsYieldFailureEAP) {
  ScopedMockLog log;
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  SetCurrentService(service);
  ReportEAPEvent(wpa_supplicant::kEAPStatusStarted, "");
  EXPECT_FALSE(service->has_ever_connected());

  EXPECT_CALL(*service, SetFailure(Service::kFailureEAPAuthentication));
  EXPECT_CALL(*service, SetFailureSilent(_)).Times(0);
  EXPECT_CALL(*service, SetState(_)).Times(0);
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith(shill::kErrorEapAuthenticationFailed)));
  ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
}

// Scanning tests will use a mock of the event dispatcher instead of a real
// one.
class WiFiTimerTest : public WiFiObjectTest {
 public:
  WiFiTimerTest() : WiFiObjectTest(&mock_dispatcher_) {}

 protected:
  void ExpectInitialScanSequence();

  StrictMock<MockEventDispatcher> mock_dispatcher_;
};

void WiFiTimerTest::ExpectInitialScanSequence() {
  // Choose a number of iterations some multiple higher than the fast scan
  // count.
  const int kScanTimes = WiFi::kNumFastScanAttempts * 4;

  // Each time we call FireScanTimer() below, WiFi will post a task to actually
  // run Scan() on the wpa_supplicant proxy.
  EXPECT_CALL(mock_dispatcher_, PostTask(_))
      .Times(kScanTimes);
  {
    InSequence seq;
    // The scans immediately after the initial scan should happen at the short
    // interval.  If we add the initial scan (not invoked in this function) to
    // the ones in the expectation below, we get WiFi::kNumFastScanAttempts at
    // the fast scan interval.
    EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
        _, WiFi::kFastScanIntervalSeconds * 1000))
        .Times(WiFi::kNumFastScanAttempts - 1)
        .WillRepeatedly(Return(true));

    // After this, the WiFi device should use the normal scan interval.
    EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
        _, GetScanInterval() * 1000))
        .Times(kScanTimes - WiFi::kNumFastScanAttempts + 1)
        .WillRepeatedly(Return(true));

    for (int i = 0; i < kScanTimes; i++) {
      FireScanTimer();
    }
  }
}

TEST_F(WiFiTimerTest, FastRescan) {
  // This PostTask is a result of the call to Scan(NULL), and is meant to
  // post a task to call Scan() on the wpa_supplicant proxy immediately.
  EXPECT_CALL(mock_dispatcher_, PostTask(_));
  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, WiFi::kFastScanIntervalSeconds * 1000))
      .WillOnce(Return(true));
  StartWiFi();

  ExpectInitialScanSequence();

  // If we end up disconnecting, the sequence should repeat.
  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, WiFi::kFastScanIntervalSeconds * 1000))
      .WillOnce(Return(true));
  RestartFastScanAttempts();

  ExpectInitialScanSequence();
}

TEST_F(WiFiTimerTest, ReconnectTimer) {
  EXPECT_CALL(mock_dispatcher_, PostTask(_)).Times(AnyNumber());
  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(_, _)).Times(AnyNumber());
  SetupConnectedService(DBus::Path());
  Mock::VerifyAndClearExpectations(&mock_dispatcher_);

  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, GetReconnectTimeoutSeconds() * 1000)).Times(1);
  StartReconnectTimer();
  Mock::VerifyAndClearExpectations(&mock_dispatcher_);
  StopReconnectTimer();

  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, GetReconnectTimeoutSeconds() * 1000)).Times(1);
  StartReconnectTimer();
  Mock::VerifyAndClearExpectations(&mock_dispatcher_);
  GetReconnectTimeoutCallback().callback().Run();

  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, GetReconnectTimeoutSeconds() * 1000)).Times(1);
  StartReconnectTimer();
  Mock::VerifyAndClearExpectations(&mock_dispatcher_);

  EXPECT_CALL(mock_dispatcher_, PostDelayedTask(
      _, GetReconnectTimeoutSeconds() * 1000)).Times(0);
  StartReconnectTimer();
}

TEST_F(WiFiMainTest, EAPCertification) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  EXPECT_CALL(*service, AddEAPCertification(_, _)).Times(0);

  ScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _, EndsWith("no current service.")));
  map<string, ::DBus::Variant> args;
  ReportCertification(args);
  Mock::VerifyAndClearExpectations(&log);

  SetCurrentService(service);
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _, EndsWith("no depth parameter.")));
  ReportCertification(args);
  Mock::VerifyAndClearExpectations(&log);

  const uint32 kDepth = 123;
  args[wpa_supplicant::kInterfacePropertyDepth].writer().append_uint32(kDepth);

  EXPECT_CALL(log,
              Log(logging::LOG_ERROR, _, EndsWith("no subject parameter.")));
  ReportCertification(args);
  Mock::VerifyAndClearExpectations(&log);

  const string kSubject("subject");
  args[wpa_supplicant::kInterfacePropertySubject].writer()
      .append_string(kSubject.c_str());
  EXPECT_CALL(*service, AddEAPCertification(kSubject, kDepth)).Times(1);
  ReportCertification(args);
}

TEST_F(WiFiMainTest, EAPEvent) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  EXPECT_CALL(*service, SetFailure(_)).Times(0);

  ScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _, EndsWith("no current service.")));
  ReportEAPEvent(string(), string());
  Mock::VerifyAndClearExpectations(&log);

  SetCurrentService(service);
  const string kEAPMethod("EAP-ROCHAMBEAU");
  EXPECT_CALL(log, Log(logging::LOG_INFO, _,
                       EndsWith("accepted EAP method " + kEAPMethod)));
  ReportEAPEvent(wpa_supplicant::kEAPStatusAcceptProposedMethod, kEAPMethod);

  EXPECT_CALL(log, Log(_, _, EndsWith("Completed authentication."))).Times(1);
  ReportEAPEvent(wpa_supplicant::kEAPStatusCompletion,
                 wpa_supplicant::kEAPParameterSuccess);

  Mock::VerifyAndClearExpectations(&log);
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());

  // An EAP failure without a previous TLS indication yields a generic failure.
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_CALL(*service,
              SetFailure(Service::kFailureEAPAuthentication)).Times(1);
  ReportEAPEvent(wpa_supplicant::kEAPStatusCompletion,
                 wpa_supplicant::kEAPParameterFailure);
  Mock::VerifyAndClearExpectations(service.get());

  // An EAP failure with a previous TLS indication yields a specific failure.
  SetCurrentService(service);
  EXPECT_CALL(*service, SetFailure(_)).Times(0);
  ReportEAPEvent(wpa_supplicant::kEAPStatusLocalTLSAlert, string());
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_CALL(*service, SetFailure(Service::kFailureEAPLocalTLS)).Times(1);
  ReportEAPEvent(wpa_supplicant::kEAPStatusCompletion,
                 wpa_supplicant::kEAPParameterFailure);
  Mock::VerifyAndClearExpectations(service.get());

  SetCurrentService(service);
  EXPECT_CALL(*service, SetFailure(_)).Times(0);
  ReportEAPEvent(wpa_supplicant::kEAPStatusRemoteTLSAlert, string());
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_CALL(*service, SetFailure(Service::kFailureEAPRemoteTLS)).Times(1);
  ReportEAPEvent(wpa_supplicant::kEAPStatusCompletion,
                 wpa_supplicant::kEAPParameterFailure);
  Mock::VerifyAndClearExpectations(service.get());

  SetCurrentService(service);
  EXPECT_CALL(*service, SetFailure(_)).Times(0);
  const string kStrangeParameter("ennui");
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,EndsWith(
      string("Unexpected ") +
      wpa_supplicant::kEAPStatusRemoteCertificateVerification +
      " parameter: " + kStrangeParameter)));
  ReportEAPEvent(wpa_supplicant::kEAPStatusRemoteCertificateVerification,
                 kStrangeParameter);
}

TEST_F(WiFiMainTest, PendingScanDoesNotCrashAfterStop) {
  // Scan is one task that should be skipped after Stop. Others are
  // skipped by the same mechanism (invalidating weak pointers), so we
  // don't test them individually.
  //
  // Note that we can't test behavior by setting expectations on the
  // supplicant_interface_proxy_, since that is destroyed when we StopWiFi().
  StartWiFi();
  StopWiFi();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, VerifyPaths) {
  string path = WiFi::kSupplicantConfPath;
  TrimString(path, FilePath::kSeparators, &path);
  EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)));
}

struct BSS {
  string bsspath;
  string ssid;
  string bssid;
  int16_t signal_strength;
  uint16 frequency;
  const char* mode;
};

TEST_F(WiFiMainTest, GetGeolocationObjects) {
  BSS bsses[] = {
    {"bssid1", "ssid1", "00:00:00:00:00:00", 5, Metrics::kWiFiFrequency2412,
     kNetworkModeInfrastructure},
    {"bssid2", "ssid2", "01:00:00:00:00:00", 30, Metrics::kWiFiFrequency5170,
     kNetworkModeInfrastructure},
    // Same SSID but different BSSID is an additional geolocation object.
    {"bssid3", "ssid1", "02:00:00:00:00:00", 100, 0,
     kNetworkModeInfrastructure}
  };
  StartWiFi();
  vector<GeolocationInfo> objects;
  EXPECT_EQ(objects.size(), 0);

  for (size_t i = 0; i < arraysize(bsses); ++i) {
    ReportBSS(bsses[i].bsspath, bsses[i].ssid, bsses[i].bssid,
              bsses[i].signal_strength, bsses[i].frequency, bsses[i].mode);
    objects = wifi()->GetGeolocationObjects();
    EXPECT_EQ(objects.size(), i + 1);

    GeolocationInfo expected_info;
    expected_info.AddField(kGeoMacAddressProperty, bsses[i].bssid);
    expected_info.AddField(kGeoSignalStrengthProperty,
                           StringPrintf("%d", bsses[i].signal_strength));
    expected_info.AddField(kGeoChannelProperty, StringPrintf(
        "%d", Metrics::WiFiFrequencyToChannel(bsses[i].frequency)));
    EXPECT_TRUE(objects[i].Equals(expected_info));
  };
};

TEST_F(WiFiMainTest, SetSupplicantDebugLevel) {
  MockSupplicantProcessProxy *process_proxy = supplicant_process_proxy_.get();

  // With WiFi not yet started, nothing interesting (including a crash) should
  // happen.
  EXPECT_CALL(*process_proxy, GetDebugLevel()).Times(0);
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  ReportWiFiDebugScopeChanged(true);

  // This unit test turns on WiFi debugging, so when we start WiFi, we should
  // check but not set the debug level if we return the "debug" level.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelDebug));
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  StartWiFi();
  Mock::VerifyAndClearExpectations(process_proxy);

  // If WiFi debugging is toggled and wpa_supplicant reports debugging
  // is set to some unmanaged level, WiFi should leave it alone.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelError))
      .WillOnce(Return(wpa_supplicant::kDebugLevelError))
      .WillOnce(Return(wpa_supplicant::kDebugLevelExcessive))
      .WillOnce(Return(wpa_supplicant::kDebugLevelExcessive))
      .WillOnce(Return(wpa_supplicant::kDebugLevelMsgDump))
      .WillOnce(Return(wpa_supplicant::kDebugLevelMsgDump))
      .WillOnce(Return(wpa_supplicant::kDebugLevelWarning))
      .WillOnce(Return(wpa_supplicant::kDebugLevelWarning));
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);
  Mock::VerifyAndClearExpectations(process_proxy);

  // If WiFi debugging is turned off and wpa_supplicant reports debugging
  // is turned on, WiFi should turn supplicant debugging off.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelDebug));
  EXPECT_CALL(*process_proxy, SetDebugLevel(wpa_supplicant::kDebugLevelInfo))
      .Times(1);
  ReportWiFiDebugScopeChanged(false);
  Mock::VerifyAndClearExpectations(process_proxy);

  // If WiFi debugging is turned on and wpa_supplicant reports debugging
  // is turned off, WiFi should turn supplicant debugging on.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelInfo));
  EXPECT_CALL(*process_proxy, SetDebugLevel(wpa_supplicant::kDebugLevelDebug))
      .Times(1);
  ReportWiFiDebugScopeChanged(true);
  Mock::VerifyAndClearExpectations(process_proxy);

  // If WiFi debugging is already in the correct state, it should not be
  // changed.
  EXPECT_CALL(*process_proxy, GetDebugLevel())
      .WillOnce(Return(wpa_supplicant::kDebugLevelDebug))
      .WillOnce(Return(wpa_supplicant::kDebugLevelInfo));
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);

  // After WiFi is stopped, we shouldn't be calling the proxy.
  EXPECT_CALL(*process_proxy, GetDebugLevel()).Times(0);
  EXPECT_CALL(*process_proxy, SetDebugLevel(_)).Times(0);
  StopWiFi();
  ReportWiFiDebugScopeChanged(true);
  ReportWiFiDebugScopeChanged(false);
}

}  // namespace shill
