// 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 <linux/if.h>
#include <linux/netlink.h>  // Needs typedefs from sys/socket.h.
#include <netinet/ether.h>
#include <sys/socket.h>

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

#include <base/file_util.h>
#include <base/memory/ref_counted.h>
#include <base/memory/scoped_ptr.h>
#include <base/string_number_conversions.h>
#include <base/string_split.h>
#include <base/string_util.h>
#include <base/stringprintf.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_netlink_manager.h"
#include "shill/mock_profile.h"
#include "shill/mock_rtnl_handler.h"
#include "shill/mock_scan_session.h"
#include "shill/mock_store.h"
#include "shill/mock_supplicant_bss_proxy.h"
#include "shill/mock_supplicant_eap_state_handler.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_provider.h"
#include "shill/mock_wifi_service.h"
#include "shill/netlink_message_matchers.h"
#include "shill/nice_mock_control.h"
#include "shill/nl80211_message.h"
#include "shill/property_store_unittest.h"
#include "shill/proxy_factory.h"
#include "shill/scan_session.h"
#include "shill/technology.h"
#include "shill/wifi_endpoint.h"
#include "shill/wifi_service.h"
#include "shill/wpa_supplicant.h"


using base::FilePath;
using std::map;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::DefaultValue;
using ::testing::DoAll;
using ::testing::EndsWith;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::MakeMatcher;
using ::testing::Matcher;
using ::testing::MatcherInterface;
using ::testing::MatchResultListener;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SaveArg;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Test;
using ::testing::Throw;
using ::testing::Values;

namespace shill {

namespace {

const uint16_t kNl80211FamilyId = 0x13;
const uint16_t kRandomScanFrequency1 = 5600;
const uint16_t kRandomScanFrequency2 = 5560;
const uint16_t kRandomScanFrequency3 = 2422;

}  // namespace

class WiFiPropertyTest : public PropertyStoreTest {
 public:
  WiFiPropertyTest()
      : device_(new WiFi(control_interface(),
                         NULL, NULL, manager(), "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));
    ASSERT_TRUE(error.is_set());  // name() may be invalid otherwise
    EXPECT_EQ(invalid_args(), error.name());
  }

  {
    ::DBus::Error error;
    EXPECT_TRUE(DBusAdaptor::SetProperty(
        device_->mutable_store(),
        flimflam::kBgscanMethodProperty,
        DBusAdaptor::StringToVariant(
            WPASupplicant::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(WPASupplicant::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(WPASupplicant::kNetworkBgscanMethodSimple, method);

  ::DBus::Error error;
  EXPECT_TRUE(DBusAdaptor::SetProperty(
      device_->mutable_store(),
      flimflam::kBgscanMethodProperty,
      DBusAdaptor::StringToVariant(
          WPASupplicant::kNetworkBgscanMethodLearn),
      &error));
  EXPECT_EQ(WPASupplicant::kNetworkBgscanMethodLearn, device_->bgscan_method_);
  EXPECT_TRUE(device_->store().GetStringProperty(
      flimflam::kBgscanMethodProperty, &method, &unused_error));
  EXPECT_EQ(WPASupplicant::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());
}

MATCHER_P(EndpointMatch, endpoint, "") {
  return
      arg->ssid() == endpoint->ssid() &&
      arg->network_mode() == endpoint->network_mode() &&
      arg->security_mode() == endpoint->security_mode();
}


class WiFiObjectTest : public ::testing::TestWithParam<string> {
 public:
  explicit WiFiObjectTest(EventDispatcher *dispatcher)
      : event_dispatcher_(dispatcher),
        metrics_(NULL),
        manager_(&control_interface_, NULL, &metrics_, &glib_),
        device_info_(&control_interface_, dispatcher, &metrics_, &manager_),
        wifi_(new WiFi(&control_interface_,
                       dispatcher,
                       &metrics_,
                       &manager_,
                       kDeviceName,
                       kDeviceAddress,
                       0)),
        bss_counter_(0),
        supplicant_process_proxy_(new NiceMock<MockSupplicantProcessProxy>()),
        supplicant_bss_proxy_(
            new NiceMock<MockSupplicantBSSProxy>()),
        dhcp_config_(new MockDHCPConfig(&control_interface_,
                                        kDeviceName)),
        dbus_manager_(new NiceMock<MockDBusManager>()),
        eap_state_handler_(new NiceMock<MockSupplicantEAPStateHandler>()),
        supplicant_interface_proxy_(
            new NiceMock<MockSupplicantInterfaceProxy>()),
        proxy_factory_(this) {
    InstallMockScanSession();
    ::testing::DefaultValue< ::DBus::Path>::Set("/default/path");

    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));
    Nl80211Message::SetMessageType(kNl80211FamilyId);

    // Transfers ownership.
    manager_.dbus_manager_.reset(dbus_manager_);
    wifi_->eap_state_handler_.reset(eap_state_handler_);

    wifi_->provider_ = &wifi_provider_;
    wifi_->time_ = &time_;
    wifi_->netlink_manager_ = &netlink_manager_;
    wifi_->progressive_scan_enabled_ = true;

    // The following is only useful when a real |ScanSession| is used; it is
    // ignored by |MockScanSession|.
    wifi_->all_scan_frequencies_.insert(kRandomScanFrequency1);
    wifi_->all_scan_frequencies_.insert(kRandomScanFrequency2);
    wifi_->all_scan_frequencies_.insert(kRandomScanFrequency3);
  }

  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(*supplicant_bss_proxy_, Die()).Times(AnyNumber());
  }

  virtual void TearDown() {
    EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(_))
       .WillRepeatedly(Return(reinterpret_cast<WiFiService *>(NULL)));
    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 ResetPendingService() {
    SetPendingService(NULL);
  }

  size_t GetScanFrequencyCount() const {
    return wifi_->all_scan_frequencies_.size();
  }

  void SetScanSize(int min, int max) {
    wifi_->min_frequencies_to_scan_ = min;
    wifi_->max_frequencies_to_scan_ = max;
  }

  // This clears WiFi::scan_session_, thereby allowing WiFi::Scan to create a
  // real scan session.
  void ClearScanSession() {
    wifi_->scan_session_.reset();
  }

  bool IsScanSessionNull() {
    return !wifi_->scan_session_;
  }

  void InstallMockScanSession() {
    WiFiProvider::FrequencyCountList previous_frequencies;
    std::set<uint16_t> available_frequencies;
    ScanSession::FractionList fractions;
    ScanSession::OnScanFailed null_callback;
    scan_session_ = new MockScanSession(&netlink_manager_,
                                        event_dispatcher_,
                                        previous_frequencies,
                                        available_frequencies,
                                        0,
                                        fractions,
                                        0,
                                        0,
                                        null_callback);
    wifi_->scan_session_.reset(scan_session_);
  }

  // Or DisableProgressiveScan()...
  void EnableFullScan() {
    wifi_->progressive_scan_enabled_ = false;
  }

  void OnTriggerScanResponse(const NetlinkMessage &message) {
    wifi_->scan_session_->OnTriggerScanResponse(message);
  }

 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(
        SupplicantEventDelegateInterface */*delegate*/,
        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_;
  };

  // Simulate the course of events when the last enpoint of a service is
  // removed.
  class EndpointRemovalHandler {
   public:
    EndpointRemovalHandler(WiFiRefPtr wifi, const WiFiServiceRefPtr &service)
        : wifi_(wifi), service_(service) {}
    virtual ~EndpointRemovalHandler() {}

    WiFiServiceRefPtr OnEndpointRemoved(
        const WiFiEndpointConstRefPtr &endpoint) {
      wifi_->DisassociateFromService(service_);
      return service_;
    }

   private:
    WiFiRefPtr wifi_;
    WiFiServiceRefPtr service_;
  };

  EndpointRemovalHandler *MakeEndpointRemovalHandler(
      const WiFiServiceRefPtr &service) {
    return new EndpointRemovalHandler(wifi_, service);
  }
  void CancelScanTimer() {
    wifi_->scan_timer_callback_.Cancel();
  }
  // This function creates a new endpoint with a mode set to |mode|.  We
  // synthesize new |path| and |bssid| values, since we don't really care
  // what they are for unit tests.  If "use_ssid" is true, we used the
  // passed-in ssid, otherwise we create a synthesized value for it as well.
  WiFiEndpointRefPtr MakeNewEndpoint(const char *mode,
                                     bool use_ssid,
                                     string *ssid,
                                     string *path,
                                     string *bssid) {
    bss_counter_++;
    if (!use_ssid) {
      *ssid = base::StringPrintf("ssid%d", bss_counter_);
    }
    *path = base::StringPrintf("/interface/bss%d", bss_counter_);
    *bssid = base::StringPrintf("00:00:00:00:00:%02x", bss_counter_);
    WiFiEndpointRefPtr endpoint = MakeEndpointWithMode(*ssid, *bssid, mode);
    EXPECT_CALL(wifi_provider_,
                OnEndpointAdded(EndpointMatch(endpoint))).Times(1);
    return endpoint;
  }
  WiFiEndpointRefPtr MakeEndpoint(const string &ssid, const string &bssid) {
    return MakeEndpointWithMode(ssid, bssid, kNetworkModeInfrastructure);
  }
  WiFiEndpointRefPtr MakeEndpointWithMode(
      const string &ssid, const string &bssid, const string &mode) {
    return WiFiEndpoint::MakeOpenEndpoint(
        &proxy_factory_, NULL, ssid, bssid, mode, 0, 0);
  }
  MockWiFiServiceRefPtr MakeMockServiceWithSSID(
      vector<uint8_t> ssid, const std::string &security) {
    return new NiceMock<MockWiFiService>(
        &control_interface_,
        event_dispatcher_,
        &metrics_,
        &manager_,
        &wifi_provider_,
        ssid,
        flimflam::kModeManaged,
        security,
        false);
  }
  MockWiFiServiceRefPtr MakeMockService(const std::string &security) {
    return MakeMockServiceWithSSID(vector<uint8_t>(1, 'a'), security);
  }
  ::DBus::Path MakeNewEndpointAndService(int16_t signal_strength,
                                         uint16 frequency,
                                         const char *mode,
                                         WiFiEndpointRefPtr *endpoint_ptr,
                                         MockWiFiServiceRefPtr *service_ptr) {
    string ssid;
    ::DBus::Path path;
    string bssid;
    WiFiEndpointRefPtr endpoint =
        MakeNewEndpoint(mode, false, &ssid, &path, &bssid);
    MockWiFiServiceRefPtr service =
        MakeMockServiceWithSSID(endpoint->ssid(), endpoint->security_mode());
    EXPECT_CALL(wifi_provider_, FindServiceForEndpoint(EndpointMatch(endpoint)))
        .WillRepeatedly(Return(service));
    ON_CALL(*service, GetEndpointCount()).WillByDefault(Return(1));
    ReportBSS(path, ssid, bssid, signal_strength, frequency, mode);
    if (service_ptr) {
      *service_ptr = service;
    }
    if (endpoint_ptr) {
      *endpoint_ptr = endpoint;
    }
    return path;
  }
  ::DBus::Path AddEndpointToService(
      WiFiServiceRefPtr service,
      int16_t signal_strength,
      uint16 frequency,
      const char *mode,
      WiFiEndpointRefPtr *endpoint_ptr) {
    string ssid(service->ssid().begin(), service->ssid().end());
    ::DBus::Path path;
    string bssid;
    WiFiEndpointRefPtr endpoint =
        MakeNewEndpoint(mode, true, &ssid, &path, &bssid);
    EXPECT_CALL(wifi_provider_, FindServiceForEndpoint(EndpointMatch(endpoint)))
        .WillRepeatedly(Return(service));
    ReportBSS(path, ssid, bssid, signal_strength, frequency, mode);
    if (endpoint_ptr) {
      *endpoint_ptr = endpoint;
    }
    return path;
  }
  void InitiateConnect(WiFiServiceRefPtr service) {
    map<string, ::DBus::Variant> params;
    wifi_->ConnectTo(service, params);
  }
  void InitiateDisconnect(WiFiServiceRefPtr service) {
    wifi_->DisconnectFrom(service);
  }
  MockWiFiServiceRefPtr SetupConnectingService(
      const DBus::Path &network_path,
      WiFiEndpointRefPtr *endpoint_ptr,
      ::DBus::Path *bss_path_ptr) {
    if (!network_path.empty()) {
      EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(_))
          .WillOnce(Return(network_path));
      EXPECT_CALL(*GetSupplicantInterfaceProxy(), SelectNetwork(network_path));
    }

    MockWiFiServiceRefPtr service;
    WiFiEndpointRefPtr endpoint;
    ::DBus::Path bss_path(MakeNewEndpointAndService(
        0, 0, kNetworkModeAdHoc, &endpoint, &service));
    EXPECT_CALL(*service, SetState(Service::kStateAssociating));
    InitiateConnect(service);
    Mock::VerifyAndClearExpectations(service);
    EXPECT_FALSE(GetPendingTimeout().IsCancelled());
    if (endpoint_ptr) {
      *endpoint_ptr = endpoint;
    }
    if (bss_path_ptr) {
      *bss_path_ptr = bss_path;
    }
    return service;
  }

  MockWiFiServiceRefPtr SetupConnectedService(
      const DBus::Path &network_path,
      WiFiEndpointRefPtr *endpoint_ptr,
      ::DBus::Path *bss_path_ptr) {
    WiFiEndpointRefPtr endpoint;
    ::DBus::Path bss_path;
    MockWiFiServiceRefPtr service =
        SetupConnectingService(network_path, &endpoint, &bss_path);
    if (endpoint_ptr) {
      *endpoint_ptr = endpoint;
    }
    if (bss_path_ptr) {
      *bss_path_ptr = bss_path;
    }
    EXPECT_CALL(*service, NotifyCurrentEndpoint(EndpointMatch(endpoint)));
    ReportCurrentBSSChanged(bss_path);
    EXPECT_TRUE(GetPendingTimeout().IsCancelled());
    Mock::VerifyAndClearExpectations(service);

    EXPECT_CALL(*service, SetState(Service::kStateConfiguring));
    EXPECT_CALL(*dhcp_provider(), CreateConfig(_, _, _, _)).Times(AnyNumber());
    EXPECT_CALL(*dhcp_config_.get(), RequestIP()).Times(AnyNumber());
    ReportStateChanged(WPASupplicant::kInterfaceStateCompleted);
    Mock::VerifyAndClearExpectations(service);

    EXPECT_EQ(service, GetCurrentService());
    return service;
  }
  void FireScanTimer() {
    wifi_->ScanTimerHandler();
  }
  void TriggerFullScan() {
    wifi_->Scan(Device::kFullScan, 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_;
  }
  // 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 *GetSupplicantInterfaceProxyFromWiFi() {
    return dynamic_cast<MockSupplicantInterfaceProxy *>(
        wifi_->supplicant_interface_proxy_.get());
  }
  // This function returns the supplicant interface proxy whether
  // or not we have passed the instantiated object to the WiFi instance
  // from WiFiObjectTest, so tests don't need to worry about when they
  // set expectations relative to StartWiFi().
  MockSupplicantInterfaceProxy *GetSupplicantInterfaceProxy() {
    MockSupplicantInterfaceProxy *proxy = GetSupplicantInterfaceProxyFromWiFi();
    return proxy ? proxy : supplicant_interface_proxy_.get();
  }
  MockSupplicantNetworkProxy *CreateSupplicantNetworkProxy() {
    return new NiceMock<MockSupplicantNetworkProxy>();
  }
  const string &GetSupplicantState() {
    return wifi_->supplicant_state_;
  }
  void ClearCachedCredentials(const WiFiService *service) {
    return wifi_->ClearCachedCredentials(service);
  }
  void NotifyEndpointChanged(const WiFiEndpointConstRefPtr &endpoint) {
    wifi_->NotifyEndpointChanged(endpoint);
  }
  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() {
    // Eliminate |scan_session| so |ScanDoneTask| doesn't launch another scan.
    wifi_->scan_session_.reset();
    wifi_->ScanDoneTask();
    // Make a new |scan_session| so that future scanning is done with the mock.
    InstallMockScanSession();
  }
  void ReportScanDoneKeepScanSession() {
    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;
  }
  bool SetScanInterval(uint16_t interval_seconds, Error *error) {
    return wifi_->SetScanInterval(interval_seconds, error);
  }
  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_;
  }
  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();
  }

  bool SetBgscanShortInterval(const uint16 &interval, Error *error) {
    return wifi_->SetBgscanShortInterval(interval, error);
  }

  bool SetBgscanSignalThreshold(const int32 &threshold, Error *error) {
    return wifi_->SetBgscanSignalThreshold(threshold, error);
  }

  NiceMockControl *control_interface() {
    return &control_interface_;
  }

  MockMetrics *metrics() {
    return &metrics_;
  }

  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_;
  }

  MockWiFiProvider *wifi_provider() {
    return &wifi_provider_;
  }

  EventDispatcher *event_dispatcher_;
  MockScanSession *scan_session_;  // Owned by |wifi_|.
  NiceMock<MockRTNLHandler> rtnl_handler_;
  MockTime time_;

 private:
  NiceMockControl control_interface_;
  MockMetrics metrics_;
  MockGLib glib_;
  MockManager manager_;
  MockDeviceInfo device_info_;
  WiFiRefPtr wifi_;
  NiceMock<MockWiFiProvider> wifi_provider_;
  int bss_counter_;

  // 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<MockSupplicantBSSProxy> supplicant_bss_proxy_;
  MockDHCPProvider dhcp_provider_;
  scoped_refptr<MockDHCPConfig> dhcp_config_;

  // These pointers track mock objects owned by the WiFi device instance
  // and manager so we can perform expectations against them.
  MockDBusManager *dbus_manager_;
  MockSupplicantEAPStateHandler *eap_state_handler_;
  MockNetlinkManager netlink_manager_;

 private:
  scoped_ptr<MockSupplicantInterfaceProxy> supplicant_interface_proxy_;
  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[WPASupplicant::kBSSPropertySignal].writer().
      append_int16(signal_strength);
  bss_properties[WPASupplicant::kBSSPropertyFrequency].writer().
      append_uint16(frequency);
  bss_properties[WPASupplicant::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(GetSupplicantInterfaceProxyFromWiFi() == NULL);

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

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

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

  EXPECT_CALL(*dbus_manager_, WatchName(WPASupplicant::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) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint;
  WiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), &endpoint, NULL));
  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));
  scoped_ptr<EndpointRemovalHandler> handler(
      MakeEndpointRemovalHandler(service));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
      .WillOnce(Invoke(handler.get(),
                &EndpointRemovalHandler::OnEndpointRemoved));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  EXPECT_CALL(*manager(), RegisterDevice(_));
  OnSupplicantVanish();
  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, CleanStart_FullScan) {
  EnableFullScan();
  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_TRUE(GetScanTimer().IsCancelled());
  StartWiFi();
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());
}

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_TRUE(GetScanTimer().IsCancelled());
  StartWiFi();
  EXPECT_CALL(*scan_session_, InitiateScan());
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ClearCachedCredentials) {
  StartWiFi();
  DBus::Path network = "/test/path";
  WiFiServiceRefPtr service(SetupConnectedService(network, NULL, NULL));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(network));
  ClearCachedCredentials(service);
}

TEST_F(WiFiMainTest, NotifyEndpointChanged) {
  WiFiEndpointRefPtr endpoint =
      MakeEndpointWithMode("ssid", "00:00:00:00:00:00", kNetworkModeAdHoc);
  EXPECT_CALL(*wifi_provider(), OnEndpointUpdated(EndpointMatch(endpoint)));
  NotifyEndpointChanged(endpoint);
}

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

TEST_F(WiFiMainTest, RemoveNetworkWhenSupplicantReturnsNetworkUnknown) {
  DBus::Path network = "/test/path";
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), 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(*GetSupplicantInterfaceProxy(), 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(*GetSupplicantInterfaceProxy(), 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_FullScan) {
  EnableFullScan();
  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(*GetSupplicantInterfaceProxy(), Scan(_));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
}

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(*scan_session_, InitiateScan());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
}

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

TEST_F(WiFiMainTest, NoScansWhileConnecting_FullScan) {
  EnableFullScan();
  StartWiFi();
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  SetPendingService(service);
  // If we're connecting, we ignore scan requests to stay on channel.
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(true));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(false));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  // Similarly, ignore scans when our connected service is reconnecting.
  SetPendingService(NULL);
  SetCurrentService(service);
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(true));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  // But otherwise we'll honor the request.
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(false));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
}

TEST_F(WiFiMainTest, NoScansWhileConnecting) {
  StartWiFi();
  EXPECT_CALL(*scan_session_, InitiateScan());
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  SetPendingService(service);
  // If we're connecting, we ignore scan requests to stay on channel.
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(true));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(false));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  // Similarly, ignore scans when our connected service is reconnecting.
  SetPendingService(NULL);
  SetCurrentService(service);
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(true));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
  // But otherwise we'll honor the request.
  EXPECT_CALL(*service, IsConnecting()).WillOnce(Return(false));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  TriggerFullScan();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  Mock::VerifyAndClearExpectations(service);
}

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

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

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

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

TEST_F(WiFiMainTest, ResumeDoesNotStartScanWhenNotIdle_FullScan) {
  EnableFullScan();
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  WiFiServiceRefPtr service(SetupConnectedService(DBus::Path(), NULL, NULL));
  EXPECT_FALSE(wifi()->IsIdle());
  ScopedMockLog log;
  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, ResumeDoesNotStartScanWhenNotIdle) {
  EXPECT_CALL(*scan_session_, InitiateScan());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  WiFiServiceRefPtr service(SetupConnectedService(DBus::Path(), NULL, NULL));
  EXPECT_FALSE(wifi()->IsIdle());
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, EndsWith("already scanning or connected.")));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  OnAfterResume();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ScanResults) {
  EXPECT_CALL(*wifi_provider(), OnEndpointAdded(_)).Times(5);
  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, ScanCompleted) {
  StartWiFi();
  WiFiEndpointRefPtr ap0 = MakeEndpointWithMode("ssid0", "00:00:00:00:00:00",
                                                kNetworkModeAdHoc);
  WiFiEndpointRefPtr ap1 = MakeEndpoint("ssid1", "00:00:00:00:00:01");
  WiFiEndpointRefPtr ap2 = MakeEndpoint("ssid2", "00:00:00:00:00:02");
  EXPECT_CALL(*wifi_provider(), OnEndpointAdded(EndpointMatch(ap0))).Times(1);
  EXPECT_CALL(*wifi_provider(), OnEndpointAdded(EndpointMatch(ap1))).Times(1);
  EXPECT_CALL(*wifi_provider(), OnEndpointAdded(EndpointMatch(ap2))).Times(1);
  ReportBSS("bss0", ap0->ssid_string(), ap0->bssid_string(), 0, 0,
            kNetworkModeAdHoc);
  ReportBSS("bss1", ap1->ssid_string(), ap1->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  ReportBSS("bss2", ap2->ssid_string(), ap2->bssid_string(), 0, 0,
            kNetworkModeInfrastructure);
  ReportScanDone();
  Mock::VerifyAndClearExpectations(wifi_provider());

  EXPECT_CALL(*wifi_provider(), OnEndpointAdded(_)).Times(0);

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

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

TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnected) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint;
  DBus::Path bss_path;
  WiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), &endpoint, &bss_path));
  scoped_ptr<EndpointRemovalHandler> handler(
      MakeEndpointRemovalHandler(service));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
      .WillOnce(Invoke(handler.get(),
                &EndpointRemovalHandler::OnEndpointRemoved));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  RemoveBSS(bss_path);
}

TEST_F(WiFiMainTest, NonSolitaryBSSRemoved) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint;
  DBus::Path bss_path;
  WiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), &endpoint, &bss_path));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
     .WillOnce(Return(reinterpret_cast<WiFiService *>(NULL)));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  RemoveBSS(bss_path);
}

TEST_F(WiFiMainTest, ReconnectPreservesDBusPath) {
  StartWiFi();
  DBus::Path kPath = "/test/path";
  WiFiServiceRefPtr service(SetupConnectedService(kPath, NULL, NULL));

  // Return the service to a connectable state.
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  InitiateDisconnect(service);
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());

  // Complete the disconnection by reporting a BSS change.
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);

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

TEST_F(WiFiMainTest, DisconnectPendingService) {
  StartWiFi();
  MockWiFiServiceRefPtr service(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_TRUE(GetPendingService() == service.get());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(AtLeast(1));
  InitiateDisconnect(service);
  Mock::VerifyAndClearExpectations(service.get());
  EXPECT_TRUE(GetPendingService() == NULL);
}

TEST_F(WiFiMainTest, DisconnectPendingServiceWithCurrent) {
  StartWiFi();
  MockWiFiServiceRefPtr service0(
      SetupConnectedService(DBus::Path(), NULL, NULL));
  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(NULL, GetPendingService().get());

  // We don't explicitly call Disconnect() while transitioning to a new
  // service.  Instead, we use the side-effect of SelectNetwork (verified in
  // SetupConnectingService).
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  MockWiFiServiceRefPtr service1(
      SetupConnectingService("/new/path", NULL, NULL));
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());

  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(service1, GetPendingService());
  EXPECT_CALL(*service1, SetState(Service::kStateIdle)).Times(AtLeast(1));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  InitiateDisconnect(service1);
  Mock::VerifyAndClearExpectations(service1.get());

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

TEST_F(WiFiMainTest, DisconnectCurrentService) {
  StartWiFi();
  ::DBus::Path kPath("/fake/path");
  MockWiFiServiceRefPtr service(SetupConnectedService(kPath, NULL, NULL));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), 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(
      kPath, WPASupplicant::kDBusAddr))
      .WillOnce(Return(network_proxy));
  EXPECT_CALL(*network_proxy, SetEnabled(false));
  EXPECT_CALL(*eap_state_handler_, Reset());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(kPath)).Times(0);
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
  EXPECT_EQ(NULL, GetCurrentService().get());
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
}

TEST_F(WiFiMainTest, DisconnectCurrentServiceWithErrors) {
  StartWiFi();
  DBus::Path kPath("/fake/path");
  WiFiServiceRefPtr service(SetupConnectedService(kPath, NULL, NULL));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect())
      .WillOnce(InvokeWithoutArgs(this, (&WiFiMainTest::ThrowDBusError)));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(kPath)).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) {
  StartWiFi();
  WiFiServiceRefPtr service0(SetupConnectedService(DBus::Path(), NULL, NULL));
  WiFiServiceRefPtr service1(SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_EQ(service0, GetCurrentService());
  EXPECT_EQ(service1, GetPendingService());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  InitiateDisconnect(service0);

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

TEST_F(WiFiMainTest, TimeoutPendingServiceWithEndpoints) {
  StartWiFi();
  const base::CancelableClosure &pending_timeout = GetPendingTimeout();
  EXPECT_TRUE(pending_timeout.IsCancelled());
  MockWiFiServiceRefPtr service(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_FALSE(pending_timeout.IsCancelled());
  EXPECT_EQ(service, GetPendingService());
  // Simulate a service with a wifi_ reference calling DisconnectFrom().
  EXPECT_CALL(*service, DisconnectWithFailure(Service::kFailureOutOfRange, _))
      .WillOnce(InvokeWithoutArgs(this, &WiFiObjectTest::ResetPendingService));
  EXPECT_CALL(*service, HasEndpoints()).Times(0);
  // DisconnectFrom() should not be called directly from WiFi.
  EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(0);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  pending_timeout.callback().Run();
  Mock::VerifyAndClearExpectations(service);
}

TEST_F(WiFiMainTest, TimeoutPendingServiceWithoutEndpoints) {
  StartWiFi();
  const base::CancelableClosure &pending_timeout = GetPendingTimeout();
  EXPECT_TRUE(pending_timeout.IsCancelled());
  MockWiFiServiceRefPtr service(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_FALSE(pending_timeout.IsCancelled());
  EXPECT_EQ(service, GetPendingService());
  // We expect the service to get a disconnect call, but in this scenario
  // the service does nothing.
  EXPECT_CALL(*service, DisconnectWithFailure(Service::kFailureOutOfRange, _));
  EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(false));
  // DisconnectFrom() should be called directly from WiFi.
  EXPECT_CALL(*service, SetState(Service::kStateIdle)).Times(AtLeast(1));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  pending_timeout.callback().Run();
  EXPECT_EQ(NULL, GetPendingService().get());
}

TEST_F(WiFiMainTest, DisconnectInvalidService) {
  StartWiFi();
  MockWiFiServiceRefPtr service;
  MakeNewEndpointAndService(0, 0, kNetworkModeAdHoc, NULL, &service);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect()).Times(0);
  InitiateDisconnect(service);
}

TEST_F(WiFiMainTest, DisconnectCurrentServiceFailure) {
  StartWiFi();
  DBus::Path kPath("/fake/path");
  WiFiServiceRefPtr service(SetupConnectedService(kPath, NULL, NULL));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect())
      .WillRepeatedly(Throw(
          DBus::Error(
              "fi.w1.wpa_supplicant1.NotConnected",
              "test threw fi.w1.wpa_supplicant1.NotConnected")));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(kPath));
  InitiateDisconnect(service);
  EXPECT_EQ(NULL, GetCurrentService().get());
}

TEST_F(WiFiMainTest, Stop) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint0;
  ::DBus::Path kPath("/fake/path");
  WiFiServiceRefPtr service0(SetupConnectedService(kPath, &endpoint0, NULL));
  WiFiEndpointRefPtr endpoint1;
  MakeNewEndpointAndService(0, 0, kNetworkModeAdHoc, &endpoint1, NULL);

  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint0)))
     .WillOnce(Return(reinterpret_cast<WiFiService *>(NULL)));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint1)))
     .WillOnce(Return(reinterpret_cast<WiFiService *>(NULL)));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), RemoveNetwork(kPath)).Times(1);
  StopWiFi();
  EXPECT_TRUE(GetScanTimer().IsCancelled());
  EXPECT_FALSE(wifi()->weak_ptr_factory_.HasWeakPtrs());
}

TEST_F(WiFiMainTest, StopWhileConnected) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint;
  WiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), &endpoint, NULL));
  scoped_ptr<EndpointRemovalHandler> handler(
      MakeEndpointRemovalHandler(service));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(EndpointMatch(endpoint)))
      .WillOnce(Invoke(handler.get(),
                &EndpointRemovalHandler::OnEndpointRemoved));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  StopWiFi();
  EXPECT_TRUE(GetCurrentService() == NULL);
}

TEST_F(WiFiMainTest, ReconnectTimer) {
  StartWiFi();
  MockWiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), NULL, NULL));
  EXPECT_CALL(*service, IsConnected()).WillRepeatedly(Return(true));
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(WPASupplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(WPASupplicant::kInterfaceStateCompleted);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(WPASupplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  ReportCurrentBSSChanged(kBSSName);
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
  ReportStateChanged(WPASupplicant::kInterfaceStateDisconnected);
  EXPECT_FALSE(GetReconnectTimeoutCallback().IsCancelled());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  GetReconnectTimeoutCallback().callback().Run();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  EXPECT_TRUE(GetReconnectTimeoutCallback().IsCancelled());
}


MATCHER_P(HasHiddenSSID_FullScan, ssid, "") {
  map<string, DBus::Variant>::const_iterator it =
      arg.find(WPASupplicant::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 && ssids[0] == ssid && ssids[1].empty();
}

MATCHER(HasNoHiddenSSID_FullScan, "") {
  map<string, DBus::Variant>::const_iterator it =
      arg.find(WPASupplicant::kPropertyScanSSIDs);
  return it == arg.end();
}

TEST_F(WiFiMainTest, ScanHidden_FullScan) {
  EnableFullScan();
  vector<uint8_t>kSSID(1, 'a');
  ByteArrays ssids;
  ssids.push_back(kSSID);

  StartWiFi();
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList()).WillOnce(Return(ssids));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(),
              Scan(HasHiddenSSID_FullScan(kSSID)));
  dispatcher_.DispatchPendingEvents();
}

// This test is slightly different from the test in scan_session_unittest.cc
// because this tests the piece of WiFi that builds the SSID list.
TEST_F(WiFiMainTest, ScanHidden) {
  // Clear the Mock ScanSession because hidden SSIDs are added when wifi
  // instantiates a new ScanSession (and it won't instantiate a new ScanSession
  // if there's already one there).
  ClearScanSession();
  vector<uint8_t>kSSID(1, 'a');
  ByteArrays ssids;
  ssids.push_back(kSSID);

  EXPECT_CALL(netlink_manager_, SendMessage(
      IsNl80211Command(kNl80211FamilyId, NL80211_CMD_GET_WIPHY), _));
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList()).WillOnce(Return(ssids));
  StartWiFi();
  EXPECT_CALL(netlink_manager_,
              SendMessage(HasHiddenSSID(kNl80211FamilyId), _));
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ScanNoHidden_FullScan) {
  EnableFullScan();
  StartWiFi();
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList())
      .WillOnce(Return(ByteArrays()));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(HasNoHiddenSSID_FullScan()));
  dispatcher_.DispatchPendingEvents();
}

// This test is slightly different from the test in scan_session_unittest.cc
// because this tests the piece of WiFi that builds the SSID list.
TEST_F(WiFiMainTest, ScanNoHidden) {
  // Clear the Mock ScanSession because hidden SSIDs are added when wifi
  // instantiates a new ScanSession (and it won't instantiate a new ScanSession
  // if there's already one there).
  ClearScanSession();
  EXPECT_CALL(netlink_manager_, SendMessage(
      IsNl80211Command(kNl80211FamilyId, NL80211_CMD_GET_WIPHY), _));
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList())
      .WillOnce(Return(ByteArrays()));
  StartWiFi();
  EXPECT_CALL(netlink_manager_,
              SendMessage(HasNoHiddenSSID(kNl80211FamilyId), _));
  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(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  StartWiFi();
  StopWiFi();
  // A scan is queued when WiFi resumes.
  OnAfterResume();
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ProgressiveScanFound) {
  // Set min & max scan frequency count to 1 so each scan will be of a single
  // frequency.
  SetScanSize(1, 1);

  // Do the first scan (finds nothing).
  EXPECT_CALL(*scan_session_, InitiateScan());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportScanDoneKeepScanSession();

  // Do the second scan (connects afterwards).
  EXPECT_CALL(*scan_session_, InitiateScan());
  dispatcher_.DispatchPendingEvents();
  ReportScanDoneKeepScanSession();

  // Connect after second scan.
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  SetPendingService(service);

  // Verify that the third scan aborts and there is no further scan.
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, EndsWith(
      "Ignoring scan request while connecting to an AP."))).Times(1);
  EXPECT_CALL(*metrics(), NotifyDeviceScanFinished(_));
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ProgressiveScanNotFound) {
  // Set min & max scan frequency count to 1 so each scan will be of a single
  // frequency.
  SetScanSize(1, 1);

  // Do the first scan (finds nothing).
  EXPECT_CALL(*scan_session_, InitiateScan());
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportScanDoneKeepScanSession();

  // Do the second scan (finds nothing).
  EXPECT_CALL(*scan_session_, InitiateScan());
  dispatcher_.DispatchPendingEvents();
  ReportScanDoneKeepScanSession();

  // Do the third scan. After (simulated) exhausting of search frequencies,
  // verify that this scan uses supplicant rather than internal (progressive)
  // scan.
  EXPECT_CALL(*scan_session_, HasMoreFrequencies()).WillOnce(Return(false));
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_));
  dispatcher_.DispatchPendingEvents();

  // And verify that ScanDone reports a complete scan (i.e., the
  // wifi_::scan_session_ has truly been cleared).
  EXPECT_CALL(*metrics(), NotifyDeviceScanFinished(_));
  ReportScanDoneKeepScanSession();
}

TEST_F(WiFiMainTest, ProgressiveScanError) {
  // Clear the Mock ScanSession so I can get an actual ScanSession.
  ClearScanSession();
  StartWiFi();

  // This should call |Scan| which posts |ScanTask|
  NewScanResultsMessage not_supposed_to_get_this_message;
  OnTriggerScanResponse(not_supposed_to_get_this_message);

  EXPECT_TRUE(IsScanSessionNull());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(1);
  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(WPASupplicant::kInterfaceStateScanning);
  EXPECT_EQ(WPASupplicant::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(WPASupplicant::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(WPASupplicant::kInterfaceStateCompleted);
  ReportStateChanged(WPASupplicant::kInterfaceStateAuthenticating);
  EXPECT_EQ(WPASupplicant::kInterfaceStateAuthenticating,
            GetSupplicantState());
  // Verify expectations now, because WiFi may report other state changes
  // when WiFi is Stop()-ed (during TearDown()).
  Mock::VerifyAndClearExpectations(service);
  EXPECT_CALL(*service, 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(WPASupplicant::kDebugLevelInfo));
  EXPECT_CALL(*process_proxy, SetDebugLevel(WPASupplicant::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(WPASupplicant::kDebugLevelDebug));
  EXPECT_CALL(*process_proxy, SetDebugLevel(WPASupplicant::kDebugLevelInfo))
      .Times(1);
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
}

TEST_F(WiFiMainTest, CurrentBSSChangeConnectedToDisconnected) {
  StartWiFi();
  WiFiEndpointRefPtr endpoint;
  MockWiFiServiceRefPtr service =
      SetupConnectedService(DBus::Path(), &endpoint, NULL);

  EXPECT_CALL(*service, SetState(Service::kStateIdle));
  EXPECT_CALL(*service, SetFailureSilent(Service::kFailureUnknown));
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
  EXPECT_EQ(NULL, GetCurrentService().get());
  EXPECT_EQ(NULL, GetPendingService().get());
}

TEST_F(WiFiMainTest, CurrentBSSChangeConnectedToConnectedNewService) {
  StartWiFi();
  MockWiFiServiceRefPtr service0 =
      SetupConnectedService(DBus::Path(), NULL, NULL);
  MockWiFiServiceRefPtr service1;
  ::DBus::Path bss_path1(MakeNewEndpointAndService(
      0, 0, kNetworkModeAdHoc, NULL, &service1));
  EXPECT_EQ(service0.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.
  EXPECT_CALL(*service0, SetState(Service::kStateIdle)).Times(AtLeast(1));
  ReportCurrentBSSChanged(bss_path1);
  EXPECT_CALL(*service1, SetState(Service::kStateConfiguring));
  ReportStateChanged(WPASupplicant::kInterfaceStateCompleted);
  EXPECT_EQ(service1.get(), GetCurrentService().get());
  Mock::VerifyAndClearExpectations(service0);
  Mock::VerifyAndClearExpectations(service1);
}

TEST_F(WiFiMainTest, CurrentBSSChangedUpdateServiceEndpoint) {
  StartWiFi();
  MockWiFiServiceRefPtr service =
      SetupConnectedService(DBus::Path(), NULL, NULL);
  WiFiEndpointRefPtr endpoint;
  ::DBus::Path bss_path =
      AddEndpointToService(service, 0, 0, kNetworkModeAdHoc, &endpoint);
  EXPECT_CALL(*service, NotifyCurrentEndpoint(EndpointMatch(endpoint)));
  ReportCurrentBSSChanged(bss_path);
}

TEST_F(WiFiMainTest, NewConnectPreemptsPending) {
  StartWiFi();
  MockWiFiServiceRefPtr service0(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_EQ(service0.get(), GetPendingService().get());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
  MockWiFiServiceRefPtr service1(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_EQ(service1.get(), GetPendingService().get());
  EXPECT_EQ(NULL, GetCurrentService().get());
}

TEST_F(WiFiMainTest, IsIdle) {
  StartWiFi();
  EXPECT_TRUE(wifi()->IsIdle());
  MockWiFiServiceRefPtr service(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  EXPECT_FALSE(wifi()->IsIdle());
}

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

TEST_F(WiFiMainTest, AddNetworkArgs) {
  StartWiFi();
  MockWiFiServiceRefPtr service;
  MakeNewEndpointAndService(0, 0, kNetworkModeAdHoc, NULL, &service);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(WiFiAddedArgs(true)));
  EXPECT_TRUE(SetBgscanMethod(WPASupplicant::kNetworkBgscanMethodSimple));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, AddNetworkArgsNoBgscan) {
  StartWiFi();
  MockWiFiServiceRefPtr service;
  MakeNewEndpointAndService(0, 0, kNetworkModeAdHoc, NULL, &service);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(WiFiAddedArgs(false)));
  InitiateConnect(service);
}

TEST_F(WiFiMainTest, AppendBgscan) {
  StartWiFi();
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  {
    // 1 endpoint, default bgscan method -- background scan disabled.
    std::map<std::string, DBus::Variant> params;
    EXPECT_CALL(*service, GetEndpointCount()).WillOnce(Return(1));
    AppendBgscan(service, &params);
    Mock::VerifyAndClearExpectations(service);
    EXPECT_FALSE(ContainsKey(params, WPASupplicant::kNetworkPropertyBgscan));
  }
  {
    // 2 endpoints, default bgscan method -- background scan frequency reduced.
    map<string, DBus::Variant> params;
    EXPECT_CALL(*service, GetEndpointCount()).WillOnce(Return(2));
    AppendBgscan(service, &params);
    Mock::VerifyAndClearExpectations(service);
    string config_string;
    EXPECT_TRUE(
        DBusProperties::GetString(params,
                                  WPASupplicant::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(WPASupplicant::kNetworkBgscanMethodSimple));
    std::map<std::string, DBus::Variant> params;
    EXPECT_CALL(*service, GetEndpointCount()).Times(0);
    AppendBgscan(service, &params);
    Mock::VerifyAndClearExpectations(service);
    string config_string;
    EXPECT_TRUE(
        DBusProperties::GetString(params,
                                  WPASupplicant::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(WPASupplicant::kNetworkBgscanMethodNone));
    std::map<std::string, DBus::Variant> params;
    EXPECT_CALL(*service, GetEndpointCount()).Times(0);
    AppendBgscan(service.get(), &params);
    Mock::VerifyAndClearExpectations(service);
    string config_string;
    EXPECT_FALSE(
        DBusProperties::GetString(params,
                                  WPASupplicant::kNetworkPropertyBgscan,
                                  &config_string));
  }
}

TEST_F(WiFiMainTest, StateAndIPIgnoreLinkEvent) {
  StartWiFi();
  MockWiFiServiceRefPtr service(
      SetupConnectingService(DBus::Path(), NULL, NULL));
  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);
}

TEST_F(WiFiMainTest, SupplicantCompletedAlreadyConnected) {
  StartWiFi();
  MockWiFiServiceRefPtr service(
      SetupConnectedService(DBus::Path(), NULL, NULL));
  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(WPASupplicant::kInterfaceStateCompleted);
  // When we get an IP, WiFi should enable high bitrates on the interface again.
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), EnableHighBitrates()).Times(1);
  EXPECT_CALL(*manager(), device_info()).WillOnce(Return(device_info()));
  string portal_url;
  EXPECT_CALL(*manager(), GetPortalCheckURL()).WillOnce(ReturnRef(portal_url));
  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(GetSupplicantInterfaceProxy());
  EXPECT_CALL(*service, IsConnected()).WillOnce(Return(true));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), EnableHighBitrates()).Times(1);
  ReportStateChanged(WPASupplicant::kInterfaceStateCompleted);
}

TEST_F(WiFiMainTest, BSSAddedCreatesBSSProxy) {
  // 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.
  // Get the pointer before we transfer ownership.
  MockSupplicantBSSProxy *proxy = supplicant_bss_proxy_.get();
  EXPECT_CALL(*proxy, Die());
  StartWiFi();
  DBus::Path bss_path(
      MakeNewEndpointAndService(0, 0, kNetworkModeAdHoc, NULL, NULL));
  EXPECT_CALL(*wifi_provider(), OnEndpointRemoved(_))
     .WillOnce(Return(reinterpret_cast<WiFiService *>(NULL)));
  RemoveBSS(bss_path);
  // 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};

  StartWiFi();

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

TEST_F(WiFiMainTest, ScanTimerIdle_FullScan) {
  EnableFullScan();
  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, ScanTimerIdle) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportScanDone();
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());
  EXPECT_CALL(*scan_session_, InitiateScan());
  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);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  FireScanTimer();
  dispatcher_.DispatchPendingEvents();
  EXPECT_FALSE(GetScanTimer().IsCancelled());  // Automatically re-armed.
}

TEST_F(WiFiMainTest, ScanTimerConnecting) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  MockWiFiServiceRefPtr service =
      SetupConnectingService(DBus::Path(), NULL, NULL);
  CancelScanTimer();
  EXPECT_TRUE(GetScanTimer().IsCancelled());

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

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

  SetScanInterval(1, NULL);
  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, NULL);
  EXPECT_TRUE(GetScanTimer().IsCancelled());
}

TEST_F(WiFiMainTest, ScanOnDisconnectWithHidden_FullScan) {
  EnableFullScan();
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  SetupConnectedService(DBus::Path(), NULL, NULL);
  vector<uint8_t>kSSID(1, 'a');
  ByteArrays ssids;
  ssids.push_back(kSSID);
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList())
      .WillRepeatedly(Return(ssids));
  EXPECT_CALL(*GetSupplicantInterfaceProxy(),
              Scan(HasHiddenSSID_FullScan(kSSID)));
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, ScanOnDisconnectWithHidden) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  ReportScanDone();
  SetupConnectedService(DBus::Path(), NULL, NULL);
  vector<uint8_t>kSSID(1, 'a');
  ByteArrays ssids;
  ssids.push_back(kSSID);
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList())
      .WillRepeatedly(Return(ssids));
  EXPECT_CALL(*scan_session_, InitiateScan());
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
  dispatcher_.DispatchPendingEvents();
}

TEST_F(WiFiMainTest, NoScanOnDisconnectWithoutHidden) {
  StartWiFi();
  dispatcher_.DispatchPendingEvents();
  SetupConnectedService(DBus::Path(), NULL, NULL);
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Scan(_)).Times(0);
  EXPECT_CALL(*scan_session_, InitiateScan()).Times(0);
  EXPECT_CALL(*wifi_provider(), GetHiddenSSIDList())
      .WillRepeatedly(Return(ByteArrays()));
  ReportCurrentBSSChanged(WPASupplicant::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();
  Mock::VerifyAndClearExpectations(GetSupplicantInterfaceProxy());
  EXPECT_CALL(*GetSupplicantInterfaceProxy(), Reassociate()).Times(0);
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith("Cannot reassociate."))).Times(1);
  OnLinkMonitorFailure();
}

TEST_F(WiFiMainTest, SuspectCredentialsOpen) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityNone);
  ReportStateChanged(WPASupplicant::kInterfaceState4WayHandshake);
  EXPECT_FALSE(service->has_ever_connected());
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsWPANeverConnected) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityWpa);
  ReportStateChanged(WPASupplicant::kInterfaceState4WayHandshake);
  EXPECT_FALSE(service->has_ever_connected());
  Service::ConnectFailure failure;
  EXPECT_TRUE(SuspectCredentials(*service, &failure));
  EXPECT_EQ(Service::kFailureBadPassphrase, failure);
}

TEST_F(WiFiMainTest, SuspectCredentialsWPAPreviouslyConnected) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityWpa);
  ReportStateChanged(WPASupplicant::kInterfaceState4WayHandshake);
  service->has_ever_connected_ = true;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsEAPInProgress) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  EXPECT_CALL(*eap_state_handler_, is_eap_in_progress())
      .WillOnce(Return(false))
      .WillOnce(Return(true))
      .WillOnce(Return(false))
      .WillOnce(Return(true));
  service->has_ever_connected_ = false;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
  Service::ConnectFailure failure;
  EXPECT_TRUE(SuspectCredentials(*service, &failure));
  EXPECT_EQ(Service::kFailureEAPAuthentication, failure);
  service->has_ever_connected_ = true;
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
  EXPECT_FALSE(SuspectCredentials(*service, NULL));
}

TEST_F(WiFiMainTest, SuspectCredentialsYieldFailureWPA) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurityWpa);
  SetPendingService(service);
  ReportStateChanged(WPASupplicant::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);
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith(flimflam::kErrorBadPassphrase)));
  ReportCurrentBSSChanged(WPASupplicant::kCurrentBSSNull);
}

TEST_F(WiFiMainTest, SuspectCredentialsYieldFailureEAP) {
  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  SetCurrentService(service);
  EXPECT_FALSE(service->has_ever_connected());

  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(*service, SetFailureSilent(_)).Times(0);
  EXPECT_CALL(*service, SetState(_)).Times(0);
  // Ensure that we retrieve is_eap_in_progress() before resetting the
  // EAP handler's state.
  InSequence seq;
  EXPECT_CALL(*eap_state_handler_, is_eap_in_progress())
      .WillOnce(Return(true));
  EXPECT_CALL(*service, SetFailure(Service::kFailureEAPAuthentication));
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
                       EndsWith(shill::kErrorEapAuthenticationFailed)));
  EXPECT_CALL(*eap_state_handler_, Reset());
  ReportCurrentBSSChanged(WPASupplicant::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());
  StartWiFi();
  SetupConnectedService(DBus::Path(), NULL, NULL);
  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[WPASupplicant::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[WPASupplicant::kInterfacePropertySubject].writer()
      .append_string(kSubject.c_str());
  EXPECT_CALL(*service, AddEAPCertification(kSubject, kDepth)).Times(1);
  ReportCertification(args);
}

TEST_F(WiFiMainTest, EAPEvent) {
  ScopedMockLog log;
  EXPECT_CALL(log, Log(logging::LOG_ERROR, _, EndsWith("no current service.")));
  EXPECT_CALL(*eap_state_handler_, ParseStatus(_, _, _)).Times(0);
  const string kEAPStatus("eap-status");
  const string kEAPParameter("eap-parameter");
  ReportEAPEvent(kEAPStatus, kEAPParameter);
  Mock::VerifyAndClearExpectations(&log);
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());

  MockWiFiServiceRefPtr service = MakeMockService(flimflam::kSecurity8021x);
  EXPECT_CALL(*service, SetFailure(_)).Times(0);
  EXPECT_CALL(*eap_state_handler_, ParseStatus(kEAPStatus, kEAPParameter, _));
  SetCurrentService(service);
  ReportEAPEvent(kEAPStatus, kEAPParameter);
  Mock::VerifyAndClearExpectations(service);
  Mock::VerifyAndClearExpectations(eap_state_handler_);

  EXPECT_CALL(*eap_state_handler_, ParseStatus(kEAPStatus, kEAPParameter, _))
      .WillOnce(DoAll(SetArgumentPointee<2>(Service::kFailureOutOfRange),
                Return(false)));
  EXPECT_CALL(*service, DisconnectWithFailure(Service::kFailureOutOfRange, _));
  ReportEAPEvent(kEAPStatus, kEAPParameter);
}

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(WPASupplicant::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(WPASupplicant::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(WPASupplicant::kDebugLevelError))
      .WillOnce(Return(WPASupplicant::kDebugLevelError))
      .WillOnce(Return(WPASupplicant::kDebugLevelExcessive))
      .WillOnce(Return(WPASupplicant::kDebugLevelExcessive))
      .WillOnce(Return(WPASupplicant::kDebugLevelMsgDump))
      .WillOnce(Return(WPASupplicant::kDebugLevelMsgDump))
      .WillOnce(Return(WPASupplicant::kDebugLevelWarning))
      .WillOnce(Return(WPASupplicant::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(WPASupplicant::kDebugLevelDebug));
  EXPECT_CALL(*process_proxy, SetDebugLevel(WPASupplicant::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(WPASupplicant::kDebugLevelInfo));
  EXPECT_CALL(*process_proxy, SetDebugLevel(WPASupplicant::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(WPASupplicant::kDebugLevelDebug))
      .WillOnce(Return(WPASupplicant::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);
}

TEST_F(WiFiMainTest, LogSSID) {
  EXPECT_EQ("[SSID=]", WiFi::LogSSID(""));
  EXPECT_EQ("[SSID=foo\\x5b\\x09\\x5dbar]", WiFi::LogSSID("foo[\t]bar"));
}

// Custom property setters should return false, and make no changes, if
// the new value is the same as the old value.
TEST_F(WiFiMainTest, CustomSetterNoopChange) {
  // SetBgscanShortInterval
  {
    Error error;
    static const uint16 kKnownScanInterval = 4;
    // Set to known value.
    EXPECT_TRUE(SetBgscanShortInterval(kKnownScanInterval, &error));
    EXPECT_TRUE(error.IsSuccess());
    // Set to same value.
    EXPECT_FALSE(SetBgscanShortInterval(kKnownScanInterval, &error));
    EXPECT_TRUE(error.IsSuccess());
  }

  // SetBgscanSignalThreshold
  {
    Error error;
    static const int32 kKnownSignalThreshold = 4;
    // Set to known value.
    EXPECT_TRUE(SetBgscanSignalThreshold(kKnownSignalThreshold, &error));
    EXPECT_TRUE(error.IsSuccess());
    // Set to same value.
    EXPECT_FALSE(SetBgscanSignalThreshold(kKnownSignalThreshold, &error));
    EXPECT_TRUE(error.IsSuccess());
  }

  // SetScanInterval
  {
    Error error;
    EXPECT_FALSE(SetScanInterval(GetScanInterval(), &error));
    EXPECT_TRUE(error.IsSuccess());
  }
}

}  // namespace shill
