// 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/l2tp_ipsec_driver.h"

#include <base/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/string_util.h>
#include <chromeos/vpn-manager/service_error.h>
#include <gtest/gtest.h>

#include "shill/event_dispatcher.h"
#include "shill/nice_mock_control.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_certificate_file.h"
#include "shill/mock_device_info.h"
#include "shill/mock_glib.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_nss.h"
#include "shill/mock_process_killer.h"
#include "shill/mock_vpn.h"
#include "shill/mock_vpn_service.h"
#include "shill/vpn.h"

using base::FilePath;
using std::find;
using std::map;
using std::string;
using std::vector;
using testing::_;
using testing::ElementsAreArray;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgumentPointee;
using testing::StrictMock;

namespace shill {

class L2TPIPSecDriverTest : public testing::Test,
                            public RPCTaskDelegate {
 public:
  L2TPIPSecDriverTest()
      : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
        metrics_(&dispatcher_),
        manager_(&control_, &dispatcher_, &metrics_, &glib_),
        driver_(new L2TPIPSecDriver(&control_, &dispatcher_, &metrics_,
                                    &manager_, &device_info_, &glib_)),
        service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
                                    &manager_, driver_)),
        device_(new MockVPN(&control_, &dispatcher_, &metrics_, &manager_,
                            kInterfaceName, kInterfaceIndex)),
        certificate_file_(new MockCertificateFile()),
        test_rpc_task_destroyed_(false) {
    driver_->nss_ = &nss_;
    driver_->certificate_file_.reset(certificate_file_);  // Passes ownership.
    driver_->process_killer_ = &process_killer_;
  }

  virtual ~L2TPIPSecDriverTest() {}

  virtual void SetUp() {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  virtual void TearDown() {
    driver_->child_watch_tag_ = 0;
    driver_->pid_ = 0;
    driver_->device_ = NULL;
    driver_->service_ = NULL;
    ASSERT_TRUE(temp_dir_.Delete());
  }

  void set_test_rpc_task_destroyed(bool destroyed) {
    test_rpc_task_destroyed_ = destroyed;
  }

 protected:
  static const char kInterfaceName[];
  static const int kInterfaceIndex;

  void SetArg(const string &arg, const string &value) {
    driver_->args()->SetString(arg, value);
  }

  KeyValueStore *GetArgs() {
    return driver_->args();
  }

  string GetProviderType() {
    return driver_->GetProviderType();
  }

  void SetDevice(const VPNRefPtr &device) {
    driver_->device_ = device;
  }

  void SetService(const VPNServiceRefPtr &service) {
    driver_->service_ = service;
  }

  VPNServiceRefPtr GetService() {
    return driver_->service_;
  }

  void OnConnectTimeout() {
    driver_->OnConnectTimeout();
  }

  void StartConnectTimeout(int timeout_seconds) {
    driver_->StartConnectTimeout(timeout_seconds);
  }

  bool IsConnectTimeoutStarted() {
    return driver_->IsConnectTimeoutStarted();
  }

  // Used to assert that a flag appears in the options.
  void ExpectInFlags(const vector<string> &options, const string &flag,
                     const string &value);

  FilePath SetupPSKFile();

  FilePath GetPSKFile() { return driver_->psk_file_; }

  void InvokeNotify(const string &reason, const map<string, string> &dict) {
    driver_->Notify(reason, dict);
  }

  // Inherited from RPCTaskDelegate.
  virtual void GetLogin(string *user, string *password);
  virtual void Notify(const string &reason, const map<string, string> &dict);

  base::ScopedTempDir temp_dir_;
  NiceMockControl control_;
  NiceMock<MockDeviceInfo> device_info_;
  EventDispatcher dispatcher_;
  MockMetrics metrics_;
  MockGLib glib_;
  MockManager manager_;
  L2TPIPSecDriver *driver_;  // Owned by |service_|.
  scoped_refptr<MockVPNService> service_;
  scoped_refptr<MockVPN> device_;
  MockNSS nss_;
  MockCertificateFile *certificate_file_;  // Owned by |driver_|.
  MockProcessKiller process_killer_;
  bool test_rpc_task_destroyed_;
};

namespace {

class TestRPCTask : public RPCTask {
 public:
  TestRPCTask(ControlInterface *control, L2TPIPSecDriverTest *test);
  virtual ~TestRPCTask();

 private:
  L2TPIPSecDriverTest *test_;
};

TestRPCTask::TestRPCTask(ControlInterface *control, L2TPIPSecDriverTest *test)
    : RPCTask(control, test),
      test_(test) {
  test_->set_test_rpc_task_destroyed(false);
}

TestRPCTask::~TestRPCTask() {
  test_->set_test_rpc_task_destroyed(true);
  test_ = NULL;
}

}  // namespace

const char L2TPIPSecDriverTest::kInterfaceName[] = "ppp0";
const int L2TPIPSecDriverTest::kInterfaceIndex = 123;

void L2TPIPSecDriverTest::GetLogin(string */*user*/, string */*password*/) {}

void L2TPIPSecDriverTest::Notify(
    const string &/*reason*/, const map<string, string> &/*dict*/) {}

void L2TPIPSecDriverTest::ExpectInFlags(
    const vector<string> &options, const string &flag, const string &value) {
  vector<string>::const_iterator it =
      find(options.begin(), options.end(), flag);

  EXPECT_TRUE(it != options.end());
  if (it != options.end())
    return;  // Don't crash below.
  it++;
  EXPECT_TRUE(it != options.end());
  if (it != options.end())
    return;  // Don't crash below.
  EXPECT_EQ(value, *it);
}

FilePath L2TPIPSecDriverTest::SetupPSKFile() {
  FilePath psk_file;
  EXPECT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &psk_file));
  EXPECT_FALSE(psk_file.empty());
  EXPECT_TRUE(file_util::PathExists(psk_file));
  driver_->psk_file_ = psk_file;
  return psk_file;
}

TEST_F(L2TPIPSecDriverTest, GetProviderType) {
  EXPECT_EQ(flimflam::kProviderL2tpIpsec, GetProviderType());
}

TEST_F(L2TPIPSecDriverTest, Cleanup) {
  driver_->IdleService();  // Ensure no crash.

  const unsigned int kTag = 123;
  driver_->child_watch_tag_ = kTag;
  EXPECT_CALL(glib_, SourceRemove(kTag));
  const int kPID = 123456;
  driver_->pid_ = kPID;
  EXPECT_CALL(process_killer_, Kill(kPID, _));
  driver_->device_ = device_;
  driver_->service_ = service_;
  EXPECT_CALL(*device_, OnDisconnected());
  EXPECT_CALL(*device_, SetEnabled(false));
  EXPECT_CALL(*service_, SetFailure(Service::kFailureBadPassphrase));
  driver_->rpc_task_.reset(new RPCTask(&control_, this));
  FilePath psk_file = SetupPSKFile();
  StartConnectTimeout(0);
  driver_->FailService(Service::kFailureBadPassphrase);
  EXPECT_FALSE(file_util::PathExists(psk_file));
  EXPECT_TRUE(driver_->psk_file_.empty());
  EXPECT_EQ(0, driver_->child_watch_tag_);
  EXPECT_EQ(0, driver_->pid_);
  EXPECT_FALSE(driver_->rpc_task_.get());
  EXPECT_FALSE(driver_->device_);
  EXPECT_FALSE(driver_->service_);
  EXPECT_FALSE(driver_->IsConnectTimeoutStarted());

  driver_->service_ = service_;
  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
  driver_->IdleService();
  EXPECT_FALSE(driver_->service_);
}

TEST_F(L2TPIPSecDriverTest, DeletePSKFile) {
  FilePath psk_file = SetupPSKFile();
  driver_->DeletePSKFile();
  EXPECT_FALSE(file_util::PathExists(psk_file));
  EXPECT_TRUE(driver_->psk_file_.empty());
}

TEST_F(L2TPIPSecDriverTest, InitEnvironment) {
  vector<string> env;
  driver_->rpc_task_.reset(new RPCTask(&control_, this));
  driver_->InitEnvironment(&env);
  ASSERT_EQ(2, env.size());
  EXPECT_EQ(
      string(kRPCTaskServiceVariable) + "=" + RPCTaskMockAdaptor::kRpcConnId,
      env[0]);
  EXPECT_EQ(string(kRPCTaskPathVariable) + "=" + RPCTaskMockAdaptor::kRpcId,
            env[1]);
}

TEST_F(L2TPIPSecDriverTest, InitOptionsNoHost) {
  Error error;
  vector<string> options;
  EXPECT_FALSE(driver_->InitOptions(&options, &error));
  EXPECT_EQ(Error::kInvalidArguments, error.type());
  EXPECT_TRUE(options.empty());
}

TEST_F(L2TPIPSecDriverTest, InitOptions) {
  static const char kHost[] = "192.168.2.254";
  static const char kCaCertNSS[] = "{1234}";
  static const char kPSK[] = "foobar";

  SetArg(flimflam::kProviderHostProperty, kHost);
  SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
  SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);

  FilePath empty_cert;
  EXPECT_CALL(nss_, GetDERCertfile(kCaCertNSS, _)).WillOnce(Return(empty_cert));

  const FilePath temp_dir(temp_dir_.path());
  EXPECT_CALL(manager_, run_path()).WillOnce(ReturnRef(temp_dir));

  Error error;
  vector<string> options;
  EXPECT_TRUE(driver_->InitOptions(&options, &error));
  EXPECT_TRUE(error.IsSuccess());

  ExpectInFlags(options, "--remote_host", kHost);
  ASSERT_FALSE(driver_->psk_file_.empty());
  ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
}

TEST_F(L2TPIPSecDriverTest, InitPSKOptions) {
  Error error;
  vector<string> options;
  static const char kPSK[] = "foobar";
  const FilePath bad_dir("/non/existent/directory");
  const FilePath temp_dir(temp_dir_.path());
  EXPECT_CALL(manager_, run_path())
      .WillOnce(ReturnRef(bad_dir))
      .WillOnce(ReturnRef(temp_dir));

  EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
  EXPECT_TRUE(options.empty());
  EXPECT_TRUE(error.IsSuccess());

  SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);

  EXPECT_FALSE(driver_->InitPSKOptions(&options, &error));
  EXPECT_TRUE(options.empty());
  EXPECT_EQ(Error::kInternalError, error.type());
  error.Reset();

  EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
  ASSERT_FALSE(driver_->psk_file_.empty());
  ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
  EXPECT_TRUE(error.IsSuccess());
  string contents;
  EXPECT_TRUE(
      file_util::ReadFileToString(driver_->psk_file_, &contents));
  EXPECT_EQ(kPSK, contents);
  struct stat buf;
  ASSERT_EQ(0, stat(driver_->psk_file_.value().c_str(), &buf));
  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
}

TEST_F(L2TPIPSecDriverTest, InitNSSOptions) {
  static const char kHost[] = "192.168.2.254";
  static const char kCaCertNSS[] = "{1234}";
  static const char kNSSCertfile[] = "/tmp/nss-cert";
  FilePath empty_cert;
  FilePath nss_cert(kNSSCertfile);
  SetArg(flimflam::kProviderHostProperty, kHost);
  SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
  EXPECT_CALL(nss_,
              GetDERCertfile(kCaCertNSS,
                             ElementsAreArray(kHost, arraysize(kHost) - 1)))
      .WillOnce(Return(empty_cert))
      .WillOnce(Return(nss_cert));

  vector<string> options;
  driver_->InitNSSOptions(&options);
  EXPECT_TRUE(options.empty());
  driver_->InitNSSOptions(&options);
  ExpectInFlags(options, "--server_ca_file", kNSSCertfile);
}

TEST_F(L2TPIPSecDriverTest, InitPEMOptions) {
  static const char kCaCertPEM[] = "Insert PEM encoded data here";
  static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
  FilePath empty_cert;
  FilePath pem_cert(kPEMCertfile);
  SetArg(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
  EXPECT_CALL(*certificate_file_, CreateDERFromString(kCaCertPEM))
      .WillOnce(Return(empty_cert))
      .WillOnce(Return(pem_cert));

  vector<string> options;
  driver_->InitPEMOptions(&options);
  EXPECT_TRUE(options.empty());
  driver_->InitPEMOptions(&options);
  ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
}

TEST_F(L2TPIPSecDriverTest, AppendValueOption) {
  static const char kOption[] = "--l2tpipsec-option";
  static const char kProperty[] = "L2TPIPSec.SomeProperty";
  static const char kValue[] = "some-property-value";
  static const char kOption2[] = "--l2tpipsec-option2";
  static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
  static const char kValue2[] = "some-property-value2";

  vector<string> options;
  EXPECT_FALSE(
      driver_->AppendValueOption(
          "L2TPIPSec.UnknownProperty", kOption, &options));
  EXPECT_TRUE(options.empty());

  SetArg(kProperty, "");
  EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
  EXPECT_TRUE(options.empty());

  SetArg(kProperty, kValue);
  SetArg(kProperty2, kValue2);
  EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
  EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
  EXPECT_EQ(4, options.size());
  EXPECT_EQ(kOption, options[0]);
  EXPECT_EQ(kValue, options[1]);
  EXPECT_EQ(kOption2, options[2]);
  EXPECT_EQ(kValue2, options[3]);
}

TEST_F(L2TPIPSecDriverTest, AppendFlag) {
  static const char kTrueOption[] = "--l2tpipsec-option";
  static const char kFalseOption[] = "--nol2tpipsec-option";
  static const char kProperty[] = "L2TPIPSec.SomeProperty";
  static const char kTrueOption2[] = "--l2tpipsec-option2";
  static const char kFalseOption2[] = "--nol2tpipsec-option2";
  static const char kProperty2[] = "L2TPIPSec.SomeProperty2";

  vector<string> options;
  EXPECT_FALSE(driver_->AppendFlag("L2TPIPSec.UnknownProperty",
                                   kTrueOption, kFalseOption, &options));
  EXPECT_TRUE(options.empty());

  SetArg(kProperty, "");
  EXPECT_FALSE(
      driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
  EXPECT_TRUE(options.empty());

  SetArg(kProperty, "true");
  SetArg(kProperty2, "false");
  EXPECT_TRUE(
      driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
  EXPECT_TRUE(
      driver_->AppendFlag(kProperty2, kTrueOption2, kFalseOption2, &options));
  EXPECT_EQ(2, options.size());
  EXPECT_EQ(kTrueOption, options[0]);
  EXPECT_EQ(kFalseOption2, options[1]);
}

TEST_F(L2TPIPSecDriverTest, GetLogin) {
  static const char kUser[] = "joesmith";
  static const char kPassword[] = "random-password";
  string user, password;
  SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
  driver_->GetLogin(&user, &password);
  EXPECT_TRUE(user.empty());
  EXPECT_TRUE(password.empty());
  SetArg(flimflam::kL2tpIpsecUserProperty, "");
  SetArg(flimflam::kL2tpIpsecPasswordProperty, kPassword);
  driver_->GetLogin(&user, &password);
  EXPECT_TRUE(user.empty());
  EXPECT_TRUE(password.empty());
  SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
  driver_->GetLogin(&user, &password);
  EXPECT_EQ(kUser, user);
  EXPECT_EQ(kPassword, password);
}

TEST_F(L2TPIPSecDriverTest, OnL2TPIPSecVPNDied) {
  const int kPID = 99999;
  driver_->child_watch_tag_ = 333;
  driver_->pid_ = kPID;
  driver_->service_ = service_;
  EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
  EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
  L2TPIPSecDriver::OnL2TPIPSecVPNDied(
      kPID, vpn_manager::kServiceErrorResolveHostnameFailed << 8, driver_);
  EXPECT_EQ(0, driver_->child_watch_tag_);
  EXPECT_EQ(0, driver_->pid_);
  EXPECT_FALSE(driver_->service_);
}

namespace {
MATCHER(CheckEnv, "") {
  if (!arg || !arg[0] || !arg[1] || arg[2]) {
    return false;
  }
  return StartsWithASCII(arg[0], "SHILL_TASK_", true);
}
}  // namespace

TEST_F(L2TPIPSecDriverTest, SpawnL2TPIPSecVPN) {
  Error error;
  EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
  EXPECT_TRUE(error.IsFailure());

  static const char kHost[] = "192.168.2.254";
  SetArg(flimflam::kProviderHostProperty, kHost);
  driver_->rpc_task_.reset(new RPCTask(&control_, this));

  const int kPID = 234678;
  EXPECT_CALL(glib_, SpawnAsync(_, _, CheckEnv(), _, _, _, _, _))
      .WillOnce(Return(false))
      .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
  const int kTag = 6;
  EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnL2TPIPSecVPNDied, driver_))
      .WillOnce(Return(kTag));
  error.Reset();
  EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
  EXPECT_EQ(Error::kInternalError, error.type());
  error.Reset();
  EXPECT_TRUE(driver_->SpawnL2TPIPSecVPN(&error));
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kPID, driver_->pid_);
  EXPECT_EQ(kTag, driver_->child_watch_tag_);
}

TEST_F(L2TPIPSecDriverTest, Connect) {
  EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
  static const char kHost[] = "192.168.2.254";
  SetArg(flimflam::kProviderHostProperty, kHost);
  EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).WillOnce(Return(true));
  EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
  Error error;
  driver_->Connect(service_, &error);
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
}

TEST_F(L2TPIPSecDriverTest, Disconnect) {
  driver_->device_ = device_;
  driver_->service_ = service_;
  EXPECT_CALL(*device_, OnDisconnected());
  EXPECT_CALL(*device_, SetEnabled(false));
  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
  driver_->Disconnect();
  EXPECT_FALSE(driver_->device_);
  EXPECT_FALSE(driver_->service_);
}

TEST_F(L2TPIPSecDriverTest, OnConnectionDisconnected) {
  driver_->service_ = service_;
  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
  driver_->OnConnectionDisconnected();
  EXPECT_FALSE(driver_->service_);
}

TEST_F(L2TPIPSecDriverTest, OnConnectTimeout) {
  StartConnectTimeout(0);
  SetService(service_);
  EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
  OnConnectTimeout();
  EXPECT_FALSE(GetService());
  EXPECT_FALSE(IsConnectTimeoutStarted());
}

TEST_F(L2TPIPSecDriverTest, InitPropertyStore) {
  // Sanity test property store initialization.
  PropertyStore store;
  driver_->InitPropertyStore(&store);
  const string kUser = "joe";
  Error error;
  EXPECT_TRUE(
      store.SetStringProperty(flimflam::kL2tpIpsecUserProperty, kUser, &error));
  EXPECT_TRUE(error.IsSuccess());
  EXPECT_EQ(kUser,
            GetArgs()->LookupString(flimflam::kL2tpIpsecUserProperty, ""));
}

TEST_F(L2TPIPSecDriverTest, GetProvider) {
  PropertyStore store;
  driver_->InitPropertyStore(&store);
  {
    KeyValueStore props;
    Error error;
    EXPECT_TRUE(
        store.GetKeyValueStoreProperty(
            flimflam::kProviderProperty, &props, &error));
    EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
    EXPECT_TRUE(
        props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, false));
  }
  {
    KeyValueStore props;
    SetArg(flimflam::kL2tpIpsecPasswordProperty, "random-password");
    SetArg(flimflam::kL2tpIpsecPskProperty, "random-psk");
    Error error;
    EXPECT_TRUE(
        store.GetKeyValueStoreProperty(
            flimflam::kProviderProperty, &props, &error));
    EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
    EXPECT_FALSE(
        props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, true));
    EXPECT_FALSE(props.ContainsString(flimflam::kL2tpIpsecPasswordProperty));
  }
}

TEST_F(L2TPIPSecDriverTest, ParseIPConfiguration) {
  map<string, string> config;
  config[kL2TPIPSecInternalIP4Address] = "4.5.6.7";
  config[kL2TPIPSecExternalIP4Address] = "33.44.55.66";
  config[kL2TPIPSecGatewayAddress] = "192.168.1.1";
  config[kL2TPIPSecDNS1] = "1.1.1.1";
  config[kL2TPIPSecDNS2] = "2.2.2.2";
  config[kL2TPIPSecInterfaceName] = "ppp0";
  config[kL2TPIPSecLNSAddress] = "99.88.77.66";
  config["foo"] = "bar";
  IPConfig::Properties props;
  string interface_name;
  L2TPIPSecDriver::ParseIPConfiguration(config, &props, &interface_name);
  EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
  EXPECT_EQ("4.5.6.7", props.address);
  EXPECT_EQ("33.44.55.66", props.peer_address);
  EXPECT_EQ("192.168.1.1", props.gateway);
  EXPECT_EQ("99.88.77.66", props.trusted_ip);
  ASSERT_EQ(2, props.dns_servers.size());
  EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
  EXPECT_EQ("2.2.2.2", props.dns_servers[1]);
  EXPECT_EQ("ppp0", interface_name);
  EXPECT_TRUE(props.blackhole_ipv6);
}

namespace {
MATCHER_P(IsIPAddress, address, "") {
  IPAddress ip_address(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ip_address.SetAddressFromString(address));
  return ip_address.Equals(arg);
}
}  // namespace

TEST_F(L2TPIPSecDriverTest, Notify) {
  map<string, string> config;
  config[kL2TPIPSecInterfaceName] = kInterfaceName;
  EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
      .WillOnce(Return(kInterfaceIndex));
  EXPECT_CALL(*device_, SetEnabled(true));
  EXPECT_CALL(*device_, UpdateIPConfig(_));
  SetDevice(device_);
  FilePath psk_file = SetupPSKFile();
  StartConnectTimeout(0);

  EXPECT_CALL(metrics_, SendEnumToUMA(
      Metrics::kMetricVpnDriver,
      Metrics::kVpnDriverL2tpIpsec,
      Metrics::kMetricVpnDriverMax));
  EXPECT_CALL(metrics_, SendEnumToUMA(
      Metrics::kMetricVpnRemoteAuthenticationType,
      Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk,
      Metrics::kVpnRemoteAuthenticationTypeMax));
  EXPECT_CALL(metrics_, SendEnumToUMA(
      Metrics::kMetricVpnUserAuthenticationType,
      Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword,
      Metrics::kVpnUserAuthenticationTypeMax));

  Error unused_error;
  PropertyStore store;
  driver_->InitPropertyStore(&store);
  store.SetStringProperty(flimflam::kL2tpIpsecPskProperty, "x", &unused_error);
  store.SetStringProperty(flimflam::kL2tpIpsecPasswordProperty, "y",
                          &unused_error);

  InvokeNotify(kL2TPIPSecReasonConnect, config);
  EXPECT_FALSE(file_util::PathExists(psk_file));
  EXPECT_TRUE(GetPSKFile().empty());
  EXPECT_FALSE(IsConnectTimeoutStarted());
}

TEST_F(L2TPIPSecDriverTest, NotifyDisconnected) {
  map<string, string> dict;
  driver_->device_ = device_;
  driver_->rpc_task_.reset(new TestRPCTask(&control_, this));
  EXPECT_FALSE(test_rpc_task_destroyed_);
  EXPECT_CALL(*device_, OnDisconnected());
  EXPECT_CALL(*device_, SetEnabled(false));
  driver_->Notify(kL2TPIPSecReasonDisconnect, dict);
  EXPECT_FALSE(driver_->device_);
  EXPECT_FALSE(test_rpc_task_destroyed_);
  EXPECT_FALSE(driver_->rpc_task_.get());
  dispatcher_.PostTask(MessageLoop::QuitClosure());
  dispatcher_.DispatchForever();
  EXPECT_TRUE(test_rpc_task_destroyed_);
}

TEST_F(L2TPIPSecDriverTest, VerifyPaths) {
  // Ensure that the various path constants that the L2TP/IPSec driver uses
  // actually exists in the build image.  Due to build dependencies, they should
  // already exist by the time we run unit tests.

  // The L2TPIPSecDriver path constants are absolute.  FilePath::Append asserts
  // that its argument is not an absolute path, so we need to strip the leading
  // separators.  There's nothing built into FilePath to do so.
  static const char *kPaths[] = {
    L2TPIPSecDriver::kL2TPIPSecVPNPath,
    L2TPIPSecDriver::kPPPDPlugin,
  };
  for (size_t i = 0; i < arraysize(kPaths); i++) {
    string path(kPaths[i]);
    TrimString(path, FilePath::kSeparators, &path);
    EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
        << kPaths[i];
  }
}

}  // namespace shill
