// Copyright 2018 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/vpn/vpn_service.h"

#include <string>

#include <base/memory/ptr_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>

#include "shill/error.h"
#include "shill/fake_store.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_profile.h"
#include "shill/mock_service.h"
#include "shill/mock_virtual_device.h"
#include "shill/service_property_change_test.h"
#include "shill/test_event_dispatcher.h"
#include "shill/vpn/mock_vpn_driver.h"
#include "shill/vpn/mock_vpn_provider.h"

using std::string;
using testing::_;
using testing::ByMove;
using testing::DoAll;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::ReturnRefOfCopy;
using testing::SaveArg;

namespace {

const char kInterfaceName[] = "tun0";
const int kInterfaceIndex = 123;

}  // namespace

namespace shill {

class VPNServiceTest : public testing::Test {
 public:
  VPNServiceTest()
      : interface_name_("test-interface"),
        manager_(&control_, &dispatcher_, &metrics_),
        device_info_(&manager_) {
    Service::SetNextSerialNumberForTesting(0);
    driver_ = new MockVPNDriver();
    EXPECT_CALL(*driver_, GetProviderType())
        .WillRepeatedly(Return(kProviderL2tpIpsec));
    connection_ = new NiceMock<MockConnection>(&device_info_);
    service_ = new VPNService(&manager_, base::WrapUnique(driver_));
  }

  ~VPNServiceTest() override = default;

 protected:
  void SetUp() override {
    ON_CALL(*connection_, interface_name())
        .WillByDefault(ReturnRef(interface_name_));
    ON_CALL(*connection_, ipconfig_rpc_identifier())
        .WillByDefault(ReturnRef(ipconfig_rpc_identifier_));
    manager_.set_mock_device_info(&device_info_);
    manager_.vpn_provider_ = std::make_unique<MockVPNProvider>();
    manager_.vpn_provider_->manager_ = &manager_;
    manager_.user_traffic_uids_.push_back(1000);
    manager_.UpdateProviderMapping();
  }

  void TearDown() override {
    manager_.vpn_provider_.reset();
    EXPECT_CALL(device_info_, FlushAddresses(0));
  }

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

  void SetHasEverConnected(bool connected) {
    service_->has_ever_connected_ = connected;
  }

  void SetConnectable(bool connectable) {
    service_->connectable_ = connectable;
  }

  const char* GetAutoConnOffline() { return Service::kAutoConnOffline; }

  const char* GetAutoConnNeverConnected() {
    return VPNService::kAutoConnNeverConnected;
  }

  const char* GetAutoConnVPNAlreadyActive() {
    return VPNService::kAutoConnVPNAlreadyActive;
  }

  bool IsAutoConnectable(const char** reason) const {
    return service_->IsAutoConnectable(reason);
  }

  // Takes ownership of |provider|.
  void SetVPNProvider(VPNProvider* provider) {
    manager_.vpn_provider_.reset(provider);
    manager_.UpdateProviderMapping();
  }

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

  ServiceRefPtr CreateUnderlyingService(
      ConnectionRefPtr underlying_connection) {
    auto service = new MockService(&manager_);
    service->set_mock_connection(underlying_connection);
    return service;
  }

  std::string interface_name_;
  RpcIdentifier ipconfig_rpc_identifier_;
  MockVPNDriver* driver_;  // Owned by |service_|.
  MockControl control_;
  MockMetrics metrics_;
  EventDispatcherForTest dispatcher_;
  MockManager manager_;
  MockDeviceInfo device_info_;
  scoped_refptr<NiceMock<MockConnection>> connection_;
  VPNServiceRefPtr service_;
};

TEST_F(VPNServiceTest, LogName) {
  EXPECT_EQ("vpn_l2tpipsec_0", service_->log_name());
}

TEST_F(VPNServiceTest, ConnectAlreadyConnected) {
  EXPECT_TRUE(service_->connectable());

  Error error;
  EXPECT_CALL(*driver_, ConnectAsync(_)).Times(0);
  SetServiceState(Service::kStateOnline);
  service_->Connect(&error, "in test");
  EXPECT_EQ(Error::kAlreadyConnected, error.type());
  error.Reset();
  SetServiceState(Service::kStateConfiguring);
  service_->Connect(&error, "in test");
  EXPECT_EQ(Error::kInProgress, error.type());
}

TEST_F(VPNServiceTest, Disconnect) {
  Error error;
  service_->SetState(Service::kStateConnected);
  EXPECT_CALL(*driver_, Disconnect());
  service_->Disconnect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(VPNServiceTest, CreateStorageIdentifierNoHost) {
  KeyValueStore args;
  Error error;
  args.Set<string>(kNameProperty, "vpn-name");
  EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
  EXPECT_EQ(Error::kInvalidProperty, error.type());
}

TEST_F(VPNServiceTest, CreateStorageIdentifierNoName) {
  KeyValueStore args;
  Error error;
  args.Set<string>(kProviderHostProperty, "10.8.0.1");
  EXPECT_EQ("", VPNService::CreateStorageIdentifier(args, &error));
  EXPECT_EQ(Error::kNotSupported, error.type());
}

TEST_F(VPNServiceTest, CreateStorageIdentifier) {
  KeyValueStore args;
  Error error;
  args.Set<string>(kNameProperty, "vpn-name");
  args.Set<string>(kProviderHostProperty, "10.8.0.1");
  EXPECT_EQ("vpn_10_8_0_1_vpn_name",
            VPNService::CreateStorageIdentifier(args, &error));
  EXPECT_TRUE(error.IsSuccess());
}

TEST_F(VPNServiceTest, GetStorageIdentifier) {
  EXPECT_EQ("", service_->GetStorageIdentifier());
  service_->set_storage_id("foo");
  EXPECT_EQ("foo", service_->GetStorageIdentifier());
}

TEST_F(VPNServiceTest, IsAlwaysOnVpn) {
  const string kPackage = "com.foo.vpn";
  const string kOtherPackage = "com.bar.vpn";
  EXPECT_FALSE(service_->IsAlwaysOnVpn(kPackage));

  EXPECT_CALL(*driver_, GetHost()).WillRepeatedly(Return(kPackage));
  EXPECT_FALSE(service_->IsAlwaysOnVpn(kPackage));

  EXPECT_CALL(*driver_, GetProviderType())
      .WillRepeatedly(Return(kProviderArcVpn));
  EXPECT_TRUE(service_->IsAlwaysOnVpn(kPackage));
  EXPECT_FALSE(service_->IsAlwaysOnVpn(kOtherPackage));
}

TEST_F(VPNServiceTest, Load) {
  FakeStore storage;
  static const char kStorageID[] = "storage-id";
  service_->set_storage_id(kStorageID);
  storage.SetString(kStorageID, Service::kStorageType, kTypeVPN);
  EXPECT_CALL(*driver_, Load(&storage, kStorageID)).WillOnce(Return(true));
  EXPECT_TRUE(service_->Load(&storage));
}

TEST_F(VPNServiceTest, Save) {
  FakeStore storage;
  static const char kStorageID[] = "storage-id";
  service_->set_storage_id(kStorageID);
  EXPECT_CALL(*driver_, Save(&storage, kStorageID, false))
      .WillOnce(Return(true));
  EXPECT_TRUE(service_->Save(&storage));
  std::string type;
  EXPECT_TRUE(storage.GetString(kStorageID, Service::kStorageType, &type));
  EXPECT_EQ(type, kTypeVPN);
}

TEST_F(VPNServiceTest, SaveCredentials) {
  FakeStore storage;
  static const char kStorageID[] = "storage-id";
  service_->set_storage_id(kStorageID);
  service_->set_save_credentials(true);
  EXPECT_CALL(*driver_, Save(&storage, kStorageID, true))
      .WillOnce(Return(true));
  EXPECT_TRUE(service_->Save(&storage));
}

TEST_F(VPNServiceTest, Unload) {
  service_->SetAutoConnect(true);
  service_->set_save_credentials(true);
  service_->SetState(Service::kStateConnected);
  EXPECT_CALL(*driver_, Disconnect());
  EXPECT_CALL(*driver_, UnloadCredentials());
  MockVPNProvider* provider = new MockVPNProvider;
  SetVPNProvider(provider);
  provider->services_.push_back(service_);
  service_->Unload();
  EXPECT_FALSE(service_->auto_connect());
  EXPECT_FALSE(service_->save_credentials());
  EXPECT_TRUE(provider->services_.empty());
}

TEST_F(VPNServiceTest, InitPropertyStore) {
  EXPECT_CALL(*driver_, InitPropertyStore(service_->mutable_store()));
  service_->InitDriverPropertyStore();
}

TEST_F(VPNServiceTest, EnableAndRetainAutoConnect) {
  EXPECT_FALSE(service_->retain_auto_connect());
  EXPECT_FALSE(service_->auto_connect());
  service_->EnableAndRetainAutoConnect();
  EXPECT_TRUE(service_->retain_auto_connect());
  EXPECT_FALSE(service_->auto_connect());
}

TEST_F(VPNServiceTest, IsAutoConnectableOffline) {
  EXPECT_TRUE(service_->connectable());
  const char* reason = nullptr;
  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(false));
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(GetAutoConnOffline(), reason);
}

TEST_F(VPNServiceTest, IsAutoConnectableNeverConnected) {
  EXPECT_TRUE(service_->connectable());
  EXPECT_FALSE(service_->has_ever_connected());
  const char* reason = nullptr;
  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(GetAutoConnNeverConnected(), reason);
}

TEST_F(VPNServiceTest, IsAutoConnectableVPNAlreadyActive) {
  EXPECT_TRUE(service_->connectable());
  SetHasEverConnected(true);
  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
  MockVPNProvider* provider = new MockVPNProvider;
  SetVPNProvider(provider);
  EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(true));
  const char* reason = nullptr;
  EXPECT_FALSE(IsAutoConnectable(&reason));
  EXPECT_STREQ(GetAutoConnVPNAlreadyActive(), reason);
}

TEST_F(VPNServiceTest, IsAutoConnectableNotConnectable) {
  const char* reason = nullptr;
  SetConnectable(false);
  EXPECT_FALSE(IsAutoConnectable(&reason));
}

TEST_F(VPNServiceTest, IsAutoConnectable) {
  EXPECT_TRUE(service_->connectable());
  SetHasEverConnected(true);
  EXPECT_CALL(manager_, IsConnected()).WillOnce(Return(true));
  MockVPNProvider* provider = new MockVPNProvider;
  SetVPNProvider(provider);
  EXPECT_CALL(*provider, HasActiveService()).WillOnce(Return(false));
  const char* reason = nullptr;
  EXPECT_TRUE(IsAutoConnectable(&reason));
  EXPECT_FALSE(reason);
}

TEST_F(VPNServiceTest, SetNamePropertyTrivial) {
  Error error;
  // A null change returns false, but with error set to success.
  EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
      kNameProperty, brillo::Any(service_->friendly_name()), &error));
  EXPECT_FALSE(error.IsFailure());
}

TEST_F(VPNServiceTest, SetNameProperty) {
  const string kHost = "1.2.3.4";
  driver_->args()->Set<string>(kProviderHostProperty, kHost);
  string kOldId = service_->GetStorageIdentifier();
  Error error;
  const string kName = "New Name";
  scoped_refptr<MockProfile> profile(new MockProfile(&manager_));
  EXPECT_CALL(*profile, DeleteEntry(kOldId, _));
  EXPECT_CALL(*profile, UpdateService(_));
  service_->set_profile(profile);
  EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
      kNameProperty, brillo::Any(kName), &error));
  EXPECT_NE(service_->GetStorageIdentifier(), kOldId);
  EXPECT_EQ(kName, service_->friendly_name());
}

TEST_F(VPNServiceTest, PropertyChanges) {
  TestCommonPropertyChanges(service_, GetAdaptor());
  TestAutoConnectPropertyChange(service_, GetAdaptor());

  const string kHost = "1.2.3.4";
  scoped_refptr<MockProfile> profile(new NiceMock<MockProfile>(&manager_));
  service_->set_profile(profile);
  driver_->args()->Set<string>(kProviderHostProperty, kHost);
  TestNamePropertyChange(service_, GetAdaptor());
}

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

TEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyFailsIfNoCarrier) {
  service_->SetConnection(connection_);
  EXPECT_EQ(connection_, service_->connection());

  // Simulate an error by causing GetPrimaryPhysicalService() to return nullptr.
  EXPECT_CALL(manager_, GetPrimaryPhysicalService()).WillOnce(Return(nullptr));

  Error error;
  EXPECT_EQ("", service_->GetPhysicalTechnologyProperty(&error));
  EXPECT_EQ(Error::kOperationFailed, error.type());
}

TEST_F(VPNServiceTest, GetPhysicalTechnologyPropertyOverWifi) {
  EXPECT_CALL(*connection_, technology()).Times(0);
  service_->SetConnection(connection_);
  EXPECT_EQ(connection_, service_->connection());

  scoped_refptr<NiceMock<MockConnection>> lower_connection =
      new NiceMock<MockConnection>(&device_info_);
  EXPECT_CALL(manager_, GetPrimaryPhysicalService())
      .WillOnce(Return(ByMove(CreateUnderlyingService(lower_connection))));

  // Set the type of the lower connection to "wifi" and expect that type to be
  // returned by GetPhysicalTechnologyProperty().
  EXPECT_CALL(*lower_connection, technology())
      .WillOnce(Return(Technology::kWifi));

  Error error;
  EXPECT_EQ(kTypeWifi, service_->GetPhysicalTechnologyProperty(&error));
  EXPECT_TRUE(error.IsSuccess());

  // Clear expectations now, so the Return(lower_connection) action releases
  // the reference to |lower_connection| allowing it to be destroyed now.
  Mock::VerifyAndClearExpectations(connection_.get());
  // Destroying the |lower_connection| at function exit will also call an extra
  // FlushAddresses on the |device_info_| object.
  EXPECT_CALL(device_info_, FlushAddresses(0));
}

TEST_F(VPNServiceTest, GetTethering) {
  service_->SetConnection(connection_);
  EXPECT_EQ(connection_, service_->connection());

  // Simulate an error by causing GetPrimaryPhysicalService() to return nullptr.
  EXPECT_CALL(manager_, GetPrimaryPhysicalService()).WillOnce(Return(nullptr));

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

  scoped_refptr<NiceMock<MockConnection>> lower_connection =
      new NiceMock<MockConnection>(&device_info_);

  EXPECT_CALL(*connection_, tethering()).Times(0);

  const char kTethering[] = "moon unit";
  EXPECT_CALL(*lower_connection, tethering())
      .WillOnce(ReturnRefOfCopy(string(kTethering)))
      .WillOnce(ReturnRefOfCopy(string()));

  {
    EXPECT_CALL(manager_, GetPrimaryPhysicalService())
        .WillOnce(Return(ByMove(CreateUnderlyingService(lower_connection))));
    Error error;
    EXPECT_EQ(kTethering, service_->GetTethering(&error));
    EXPECT_TRUE(error.IsSuccess());
  }
  {
    EXPECT_CALL(manager_, GetPrimaryPhysicalService())
        .WillOnce(Return(ByMove(CreateUnderlyingService(lower_connection))));
    Error error;
    EXPECT_EQ("", service_->GetTethering(&error));
    EXPECT_EQ(Error::kNotSupported, error.type());
  }

  // Clear expectations now, so the Return(lower_connection) action releases
  // the reference to |lower_connection| allowing it to be destroyed now.
  Mock::VerifyAndClearExpectations(connection_.get());
  // Destroying the |lower_connection| at function exit will also call an extra
  // FlushAddresses on the |device_info_| object.
  EXPECT_CALL(device_info_, FlushAddresses(0));
}

TEST_F(VPNServiceTest, ConfigureDeviceAndCleanupDevice) {
  scoped_refptr<MockVirtualDevice> device = new MockVirtualDevice(
      &manager_, kInterfaceName, kInterfaceIndex, Technology::kVPN);
  service_->device_ = device;

  EXPECT_CALL(*device, SetEnabled(true));
  EXPECT_CALL(*driver_, GetIPProperties())
      .WillOnce(Return(IPConfig::Properties()));
  EXPECT_CALL(*device, UpdateIPConfig(_));
  service_->ConfigureDevice();

  EXPECT_CALL(*device, SetEnabled(false));
  EXPECT_CALL(*device, DropConnection());
  service_->CleanupDevice();
  EXPECT_FALSE(service_->device_);
}

TEST_F(VPNServiceTest, ConnectFlow) {
  Error error;
  VPNDriver::EventHandler* driver_event_handler;

  // Connection
  EXPECT_CALL(*driver_, ConnectAsync(_))
      .WillOnce(DoAll(SaveArg<0>(&driver_event_handler),
                      Return(VPNDriver::kTimeoutNone)));
  service_->Connect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(Service::kStateAssociating, service_->state());

  EXPECT_CALL(*driver_, GetIPProperties())
      .WillOnce(Return(IPConfig::Properties()));
  driver_event_handler->OnDriverConnected(kInterfaceName, kInterfaceIndex);
  EXPECT_TRUE(service_->device_);
  EXPECT_EQ(Service::kStateOnline, service_->state());

  // Driver-originated reconnection
  EXPECT_CALL(*driver_, Disconnect()).Times(0);
  driver_event_handler->OnDriverReconnecting(VPNDriver::kTimeoutNone);
  EXPECT_EQ(Service::kStateAssociating, service_->state());
  EXPECT_TRUE(service_->device_);

  // Driver-originated failure
  EXPECT_CALL(*driver_, Disconnect()).Times(0);
  driver_event_handler->OnDriverFailure(Service::kFailureUnknown,
                                        Service::kErrorDetailsNone);
  EXPECT_EQ(Service::kStateFailure, service_->state());
  EXPECT_FALSE(service_->device_);

  // Connect again and disconnection
  EXPECT_CALL(*driver_, ConnectAsync(_));
  service_->Connect(&error, "in test");
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(Service::kStateAssociating, service_->state());
  EXPECT_CALL(*driver_, Disconnect());
  service_->Disconnect(&error, "in test");
  EXPECT_EQ(Service::kStateIdle, service_->state());
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_FALSE(service_->device_);
}

TEST_F(VPNServiceTest, OnPhysicalDefaultServiceChanged) {
  // Online -> no service
  ServiceRefPtr null_service;
  EXPECT_CALL(*driver_, OnDefaultPhysicalServiceEvent(
                            VPNDriver::kDefaultPhysicalServiceDown));
  service_->OnDefaultPhysicalServiceChanged(null_service);

  scoped_refptr<MockService> mock_service(new MockService(&manager_));
  scoped_refptr<MockService> mock_service2(new MockService(&manager_));

  // No service -> online
  EXPECT_CALL(*mock_service, IsOnline()).WillRepeatedly(Return(true));
  EXPECT_CALL(*driver_, OnDefaultPhysicalServiceEvent(
                            VPNDriver::kDefaultPhysicalServiceUp));
  service_->OnDefaultPhysicalServiceChanged(mock_service);

  // Online service -> another online service
  EXPECT_CALL(*mock_service2, IsOnline()).WillRepeatedly(Return(true));
  EXPECT_CALL(*driver_, OnDefaultPhysicalServiceEvent(
                            VPNDriver::kDefaultPhysicalServiceChanged));
  service_->OnDefaultPhysicalServiceChanged(mock_service2);

  // Online -> connected
  EXPECT_CALL(*mock_service2, IsOnline()).WillRepeatedly(Return(false));
  EXPECT_CALL(*driver_, OnDefaultPhysicalServiceEvent(
                            VPNDriver::kDefaultPhysicalServiceDown));
  service_->OnDefaultPhysicalServiceChanged(mock_service2);

  // Connected -> another online service
  EXPECT_CALL(*mock_service, IsOnline()).WillRepeatedly(Return(true));
  EXPECT_CALL(*driver_, OnDefaultPhysicalServiceEvent(
                            VPNDriver::kDefaultPhysicalServiceUp));
  service_->OnDefaultPhysicalServiceChanged(mock_service);
}

TEST_F(VPNServiceTest, ConnectTimeout) {
  Error error;
  VPNDriver::EventHandler* driver_event_handler;
  constexpr base::TimeDelta kTestTimeout = base::TimeDelta::FromSeconds(10);

  // Timeout triggered.
  EXPECT_CALL(*driver_, ConnectAsync(_))
      .WillRepeatedly(
          DoAll(SaveArg<0>(&driver_event_handler), Return(kTestTimeout)));
  service_->Connect(&error, "in test");
  EXPECT_CALL(*driver_, OnConnectTimeout());
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);

  // Timeout cancelled by connection success.
  service_->Connect(&error, "in test");
  EXPECT_CALL(*driver_, OnConnectTimeout()).Times(0);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout / 2);
  driver_event_handler->OnDriverConnected(kInterfaceName, kInterfaceIndex);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);
  service_->Disconnect(&error, "in test");

  // Timeout cancelled by connection failure.
  service_->Connect(&error, "in test");
  EXPECT_CALL(*driver_, OnConnectTimeout()).Times(0);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout / 2);
  driver_event_handler->OnDriverFailure(Service::kFailureUnknown,
                                        Service::kErrorDetailsNone);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);

  // No timeout
  EXPECT_CALL(*driver_, ConnectAsync(_))
      .WillRepeatedly(DoAll(SaveArg<0>(&driver_event_handler),
                            Return(VPNDriver::kTimeoutNone)));
  service_->Connect(&error, "in test");
  EXPECT_CALL(*driver_, OnConnectTimeout()).Times(0);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);
}

TEST_F(VPNServiceTest, ReconnectTimeout) {
  Error error;
  VPNDriver::EventHandler* driver_event_handler;
  constexpr base::TimeDelta kTestTimeout = base::TimeDelta::FromSeconds(10);
  EXPECT_CALL(*driver_, ConnectAsync(_))
      .WillRepeatedly(DoAll(SaveArg<0>(&driver_event_handler),
                            Return(VPNDriver::kTimeoutNone)));
  service_->Connect(&error, "in test");
  driver_event_handler->OnDriverConnected(kInterfaceName, kInterfaceIndex);

  EXPECT_CALL(*driver_, OnConnectTimeout()).Times(0);
  driver_event_handler->OnDriverReconnecting(kTestTimeout);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout / 2);

  // Timeout should be reset.
  driver_event_handler->OnDriverReconnecting(kTestTimeout);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout / 2);

  // Timeout should be cancelled.
  driver_event_handler->OnDriverReconnecting(VPNDriver::kTimeoutNone);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);

  // Timeout triggered.
  driver_event_handler->OnDriverReconnecting(kTestTimeout);
  EXPECT_CALL(*driver_, OnConnectTimeout()).Times(1);
  dispatcher_.task_environment().FastForwardBy(kTestTimeout);
}

}  // namespace shill
