//
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "shill/dhcp/dhcpv4_config.h"

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

#include <base/bind.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/strings/stringprintf.h>
#if defined(__ANDROID__)
#include <dbus/service_constants.h>
#else
#include <chromeos/dbus/service_constants.h>
#endif  // __ANDROID__

#include "shill/dhcp/mock_dhcp_provider.h"
#include "shill/dhcp/mock_dhcp_proxy.h"
#include "shill/event_dispatcher.h"
#include "shill/mock_control.h"
#include "shill/mock_dhcp_properties.h"
#include "shill/mock_log.h"
#include "shill/mock_metrics.h"
#include "shill/mock_process_manager.h"
#include "shill/mock_store.h"
#include "shill/property_store_unittest.h"
#include "shill/testing.h"

using base::Bind;
using base::FilePath;
using base::ScopedTempDir;
using base::Unretained;
using std::string;
using std::unique_ptr;
using std::vector;
using testing::_;
using testing::AnyNumber;
using testing::ContainsRegex;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::Return;
using testing::SetArgumentPointee;
using testing::Test;

namespace shill {

namespace {
const char kDeviceName[] = "eth0";
const char kHostName[] = "hostname";
const char kVendorClass[] = "vendorclass";
const char kLeaseFileSuffix[] = "leasefilesuffix";
const bool kArpGateway = true;
const bool kHasHostname = true;
const bool kHasVendorClass = true;
const bool kHasLeaseSuffix = true;
const char kStorageID[] = "dhcp_service_id";
}  // namespace

typedef scoped_refptr<DHCPv4Config> DHCPv4ConfigRefPtr;

class DHCPv4ConfigTest : public PropertyStoreTest {
 public:
  DHCPv4ConfigTest()
      : proxy_(new MockDHCPProxy()),
        metrics_(dispatcher()),
        config_(new DHCPv4Config(&control_,
                                 dispatcher(),
                                 &provider_,
                                 kDeviceName,
                                 kLeaseFileSuffix,
                                 kArpGateway,
                                 dhcp_props_,
                                 &metrics_)) {}

  virtual void SetUp() {
    config_->process_manager_ = &process_manager_;
  }

  bool StartInstance(DHCPv4ConfigRefPtr config) {
    return config->Start();
  }

  void StopInstance() {
    config_->Stop("In test");
  }

  DHCPv4ConfigRefPtr CreateMockMinijailConfig(const string& hostname,
                                              const string& vendorclass,
                                              const string& lease_suffix,
                                              bool arp_gateway);
  DHCPv4ConfigRefPtr CreateRunningConfig(const string& hostname,
                                         const string& vendorclass,
                                         const string& lease_suffix,
                                         bool arp_gateway);
  void StopRunningConfigAndExpect(DHCPv4ConfigRefPtr config,
                                  bool lease_file_exists);

 protected:
  static const int kPID;

  FilePath lease_file_;
  FilePath pid_file_;
  ScopedTempDir temp_dir_;
  unique_ptr<MockDHCPProxy> proxy_;
  MockControl control_;
  MockProcessManager process_manager_;
  MockMetrics metrics_;
  MockDHCPProvider provider_;
  MockDhcpProperties dhcp_props_;
  DHCPv4ConfigRefPtr config_;
};

const int DHCPv4ConfigTest::kPID = 123456;

DHCPv4ConfigRefPtr DHCPv4ConfigTest::CreateMockMinijailConfig(
    const string& hostname,
    const string& vendorclass,
    const string& lease_suffix,
    bool arp_gateway) {
  MockStore storage;
  DhcpProperties dhcp_props;
  if (!hostname.empty()) {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
        .WillOnce(DoAll(SetArgumentPointee<2>(string(kHostName)),
                        Return(true)));
  } else {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
        .WillOnce(Return(false));
  }
  if (!vendorclass.empty()) {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
        .WillOnce(DoAll(SetArgumentPointee<2>(string(kVendorClass)),
                        Return(true)));
  } else {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
        .WillOnce(Return(false));
  }
  dhcp_props.Load(&storage, kStorageID);
  DHCPv4ConfigRefPtr config(new DHCPv4Config(&control_,
                                             dispatcher(),
                                             &provider_,
                                             kDeviceName,
                                             lease_suffix,
                                             arp_gateway,
                                             dhcp_props,
                                             &metrics_));
  config->process_manager_ = &process_manager_;

  return config;
}

DHCPv4ConfigRefPtr DHCPv4ConfigTest::CreateRunningConfig(
    const string& hostname, const string& vendorclass,
    const string& lease_suffix, bool arp_gateway) {
  MockStore storage;
  DhcpProperties dhcp_props;
  if (!hostname.empty()) {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
        .WillOnce(DoAll(SetArgumentPointee<2>(string(kHostName)),
                        Return(true)));
  } else {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.Hostname", _))
        .WillOnce(Return(false));
  }
  if (!vendorclass.empty()) {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
        .WillOnce(DoAll(SetArgumentPointee<2>(string(kVendorClass)),
                        Return(true)));
  } else {
    EXPECT_CALL(storage, GetString(kStorageID, "DHCPProperty.VendorClass", _))
        .WillOnce(Return(false));
  }
  dhcp_props.Load(&storage, kStorageID);
  DHCPv4ConfigRefPtr config(new DHCPv4Config(&control_,
                                             dispatcher(),
                                             &provider_,
                                             kDeviceName,
                                             lease_suffix,
                                             arp_gateway,
                                             dhcp_props,
                                             &metrics_));
  config->process_manager_ = &process_manager_;
  EXPECT_CALL(process_manager_, StartProcessInMinijail(_, _, _, _, _, _, _))
      .WillOnce(Return(kPID));
  EXPECT_CALL(provider_, BindPID(kPID, IsRefPtrTo(config)));
  EXPECT_TRUE(config->Start());
  EXPECT_EQ(kPID, config->pid_);
  EXPECT_EQ(config->hostname_, hostname);
  EXPECT_EQ(config->vendor_class_, vendorclass);

  EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
  config->root_ = temp_dir_.path();
  FilePath varrun = temp_dir_.path().Append("var/run/dhcpcd");
  EXPECT_TRUE(base::CreateDirectory(varrun));
  pid_file_ = varrun.Append(base::StringPrintf("dhcpcd-%s-4.pid", kDeviceName));
  FilePath varlib = temp_dir_.path().Append("var/lib/dhcpcd");
  EXPECT_TRUE(base::CreateDirectory(varlib));
  lease_file_ =
      varlib.Append(base::StringPrintf("dhcpcd-%s.lease", kDeviceName));
  EXPECT_EQ(0, base::WriteFile(pid_file_, "", 0));
  EXPECT_EQ(0, base::WriteFile(lease_file_, "", 0));
  EXPECT_TRUE(base::PathExists(pid_file_));
  EXPECT_TRUE(base::PathExists(lease_file_));

  return config;
}

void DHCPv4ConfigTest::StopRunningConfigAndExpect(DHCPv4ConfigRefPtr config,
                                                  bool lease_file_exists) {
  ScopedMockLog log;
  // We use a non-zero exit status so that we get the log message.
  EXPECT_CALL(log, Log(_, _, ::testing::EndsWith("status 10")));
  EXPECT_CALL(provider_, UnbindPID(kPID));
  config->OnProcessExited(10);

  EXPECT_FALSE(base::PathExists(pid_file_));
  EXPECT_EQ(lease_file_exists, base::PathExists(lease_file_));
}

TEST_F(DHCPv4ConfigTest, GetIPv4AddressString) {
  EXPECT_EQ("255.255.255.255", config_->GetIPv4AddressString(0xffffffff));
  EXPECT_EQ("0.0.0.0", config_->GetIPv4AddressString(0));
  EXPECT_EQ("1.2.3.4", config_->GetIPv4AddressString(0x04030201));
}

TEST_F(DHCPv4ConfigTest, ParseClasslessStaticRoutes) {
  const string kDefaultAddress = "0.0.0.0";
  const string kDefaultDestination = kDefaultAddress + "/0";
  const string kRouter0 = "10.0.0.254";
  const string kAddress1 = "192.168.1.0";
  const string kDestination1 = kAddress1 + "/24";
  // Last gateway missing, leaving an odd number of parameters.
  const string kBrokenClasslessRoutes0 = kDefaultDestination + " " + kRouter0 +
      " " + kDestination1;
  IPConfig::Properties properties;
  EXPECT_FALSE(DHCPv4Config::ParseClasslessStaticRoutes(kBrokenClasslessRoutes0,
                                                        &properties));
  EXPECT_TRUE(properties.routes.empty());
  EXPECT_TRUE(properties.gateway.empty());

  // Gateway argument for the second route is malformed, but we were able
  // to salvage a default gateway.
  const string kBrokenRouter1 = "10.0.0";
  const string kBrokenClasslessRoutes1 = kBrokenClasslessRoutes0 + " " +
      kBrokenRouter1;
  EXPECT_FALSE(DHCPv4Config::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
                                                        &properties));
  EXPECT_TRUE(properties.routes.empty());
  EXPECT_EQ(kRouter0, properties.gateway);

  const string kRouter1 = "10.0.0.253";
  const string kRouter2 = "10.0.0.252";
  const string kClasslessRoutes0 = kDefaultDestination + " " + kRouter2 + " " +
      kDestination1 + " " + kRouter1;
  EXPECT_TRUE(DHCPv4Config::ParseClasslessStaticRoutes(kClasslessRoutes0,
                                                       &properties));
  // The old default route is preserved.
  EXPECT_EQ(kRouter0, properties.gateway);

  // The two routes (including the one which would have otherwise been
  // classified as a default route) are added to the routing table.
  EXPECT_EQ(2, properties.routes.size());
  const IPConfig::Route& route0 = properties.routes[0];
  EXPECT_EQ(kDefaultAddress, route0.host);
  EXPECT_EQ("0.0.0.0", route0.netmask);
  EXPECT_EQ(kRouter2, route0.gateway);

  const IPConfig::Route& route1 = properties.routes[1];
  EXPECT_EQ(kAddress1, route1.host);
  EXPECT_EQ("255.255.255.0", route1.netmask);
  EXPECT_EQ(kRouter1, route1.gateway);

  // A malformed routing table should not affect the current table.
  EXPECT_FALSE(DHCPv4Config::ParseClasslessStaticRoutes(kBrokenClasslessRoutes1,
                                                        &properties));
  EXPECT_EQ(2, properties.routes.size());
  EXPECT_EQ(kRouter0, properties.gateway);
}

TEST_F(DHCPv4ConfigTest, ParseConfiguration) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  conf.SetUint8(DHCPv4Config::kConfigurationKeySubnetCIDR, 16);
  conf.SetUint(DHCPv4Config::kConfigurationKeyBroadcastAddress, 0x10203040);
  {
    vector<uint32_t> routers;
    routers.push_back(0x02040608);
    routers.push_back(0x03050709);
    conf.SetUint32s(DHCPv4Config::kConfigurationKeyRouters, routers);
  }
  {
    vector<uint32_t> dns;
    dns.push_back(0x09070503);
    dns.push_back(0x08060402);
    conf.SetUint32s(DHCPv4Config::kConfigurationKeyDNS, dns);
  }
  conf.SetString(DHCPv4Config::kConfigurationKeyDomainName, "domain-name");
  {
    vector<string> search;
    search.push_back("foo.com");
    search.push_back("bar.com");
    conf.SetStrings(DHCPv4Config::kConfigurationKeyDomainSearch, search);
  }
  conf.SetUint16(DHCPv4Config::kConfigurationKeyMTU, 600);
  conf.SetString(DHCPv4Config::kConfigurationKeyHostname, "hostname");
  conf.SetString("UnknownKey", "UnknownValue");

  ByteArray isns_data{0x1, 0x2, 0x3, 0x4};
  conf.SetUint8s(DHCPv4Config::kConfigurationKeyiSNSOptionData, isns_data);

  EXPECT_CALL(metrics_,
              SendSparseToUMA(Metrics::kMetricDhcpClientMTUValue, 600));
  IPConfig::Properties properties;
  ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
  EXPECT_EQ("4.3.2.1", properties.address);
  EXPECT_EQ(16, properties.subnet_prefix);
  EXPECT_EQ("64.48.32.16", properties.broadcast_address);
  EXPECT_EQ("8.6.4.2", properties.gateway);
  ASSERT_EQ(2, properties.dns_servers.size());
  EXPECT_EQ("3.5.7.9", properties.dns_servers[0]);
  EXPECT_EQ("2.4.6.8", properties.dns_servers[1]);
  EXPECT_EQ("domain-name", properties.domain_name);
  ASSERT_EQ(2, properties.domain_search.size());
  EXPECT_EQ("foo.com", properties.domain_search[0]);
  EXPECT_EQ("bar.com", properties.domain_search[1]);
  EXPECT_EQ(600, properties.mtu);
  EXPECT_EQ("hostname", properties.accepted_hostname);
  EXPECT_EQ(isns_data.size(), properties.isns_option_data.size());
  EXPECT_FALSE(memcmp(&properties.isns_option_data[0], &isns_data[0], isns_data.size()));
}

TEST_F(DHCPv4ConfigTest, ParseConfigurationWithMinimumMTU) {
  // Even without a minimum MTU set, we should ignore a 576 value.
  KeyValueStore conf;
  conf.SetUint16(DHCPv4Config::kConfigurationKeyMTU, 576);

  IPConfig::Properties properties;
  EXPECT_CALL(metrics_,
              SendSparseToUMA(Metrics::kMetricDhcpClientMTUValue, 576));
  ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
  EXPECT_EQ(IPConfig::kUndefinedMTU, properties.mtu);
  Mock::VerifyAndClearExpectations(&metrics_);

  // With a minimum MTU set, values below the minimum should be ignored.
  config_->set_minimum_mtu(1500);
  conf.RemoveUint16(DHCPv4Config::kConfigurationKeyMTU);
  conf.SetUint16(DHCPv4Config::kConfigurationKeyMTU, 1499);
  EXPECT_CALL(metrics_,
              SendSparseToUMA(Metrics::kMetricDhcpClientMTUValue, 1499));
  ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
  EXPECT_EQ(IPConfig::kUndefinedMTU, properties.mtu);
  Mock::VerifyAndClearExpectations(&metrics_);

  // A value (other than 576) should be accepted if it is >= mimimum_mtu.
  config_->set_minimum_mtu(577);
  conf.RemoveUint16(DHCPv4Config::kConfigurationKeyMTU);
  conf.SetUint16(DHCPv4Config::kConfigurationKeyMTU, 577);
  EXPECT_CALL(metrics_,
              SendSparseToUMA(Metrics::kMetricDhcpClientMTUValue, 577));
  ASSERT_TRUE(config_->ParseConfiguration(conf, &properties));
  EXPECT_EQ(577, properties.mtu);
}

MATCHER_P4(IsDHCPCDArgs,
           has_hostname,
           has_vendorclass,
           has_arp_gateway,
           has_lease_suffix, "") {
  if (arg[0] != "-B" ||
      arg[1] != "-q" ||
      arg[2] != "-4") {
    return false;
  }

  int end_offset = 3;
  if (has_hostname) {
    if (arg[end_offset] != "-h" ||
        arg[end_offset + 1] != kHostName) {
      return false;
    }
    end_offset += 2;
  }

  if (has_vendorclass){
    if (arg[end_offset] != "-i" ||
        arg[end_offset + 1] != kVendorClass) {
      return false;
    }
    end_offset += 2;
  }

  if (has_arp_gateway) {
    if (arg[end_offset] != "-R" ||
        arg[end_offset + 1] != "-P") {
      return false;
    }
    end_offset += 2;
  }

  string device_arg = has_lease_suffix ?
      string(kDeviceName) + "=" + string(kLeaseFileSuffix) : kDeviceName;
  return arg[end_offset] == device_arg;
}

TEST_F(DHCPv4ConfigTest, StartWithHostname) {
  config_->hostname_ = kHostName;
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(kHasHostname,
                                                  !kHasVendorClass,
                                                  kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config_));
}

TEST_F(DHCPv4ConfigTest, StartWithoutHostname) {
  DHCPv4ConfigRefPtr config = CreateMockMinijailConfig("",
                                                       "",
                                                       kLeaseFileSuffix,
                                                       kArpGateway);
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(!kHasHostname,
                                                  !kHasVendorClass,
                                                  kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config));
}

TEST_F(DHCPv4ConfigTest, StartWithEmptyHostname) {
  DHCPv4ConfigRefPtr config = CreateMockMinijailConfig("",
                                                       "",
                                                       kLeaseFileSuffix,
                                                       kArpGateway);
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(!kHasHostname,
                                                  !kHasVendorClass,
                                                  kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config));
}

TEST_F(DHCPv4ConfigTest, StartWithVendorClass) {
  config_->hostname_ = kHostName;
  config_->vendor_class_ = kVendorClass;
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(kHasHostname,
                                                  kHasVendorClass,
                                                  kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config_));
}

TEST_F(DHCPv4ConfigTest, StartWithoutVendorClass) {
  DHCPv4ConfigRefPtr config = CreateMockMinijailConfig(kHostName,
                                                       "",
                                                       kLeaseFileSuffix,
                                                       kArpGateway);
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(kHasHostname,
                                                  !kHasVendorClass,
                                                  kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config));
}


TEST_F(DHCPv4ConfigTest, StartWithoutArpGateway) {
  DHCPv4ConfigRefPtr config = CreateMockMinijailConfig(kHostName,
                                                       "",
                                                       kLeaseFileSuffix,
                                                       !kArpGateway);
  EXPECT_CALL(process_manager_,
              StartProcessInMinijail(_, _,
                                     IsDHCPCDArgs(kHasHostname,
                                                  !kHasVendorClass,
                                                  !kArpGateway,
                                                  kHasLeaseSuffix), _, _, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartInstance(config));
}

namespace {

class DHCPv4ConfigCallbackTest : public DHCPv4ConfigTest {
 public:
  virtual void SetUp() {
    DHCPv4ConfigTest::SetUp();
    config_->RegisterUpdateCallback(
        Bind(&DHCPv4ConfigCallbackTest::SuccessCallback, Unretained(this)));
    config_->RegisterFailureCallback(
        Bind(&DHCPv4ConfigCallbackTest::FailureCallback, Unretained(this)));
    ip_config_ = config_;
  }

  MOCK_METHOD2(SuccessCallback,
               void(const IPConfigRefPtr& ipconfig, bool new_lease_acquired));
  MOCK_METHOD1(FailureCallback, void(const IPConfigRefPtr& ipconfig));

  // The mock methods above take IPConfigRefPtr because this is the type
  // that the registered callbacks take.  This conversion of the DHCP
  // config ref pointer eases our work in setting up expectations.
  const IPConfigRefPtr& ConfigRef() { return ip_config_; }

 private:
  IPConfigRefPtr ip_config_;
};

}  // namespace

TEST_F(DHCPv4ConfigCallbackTest, ProcessEventSignalFail) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  EXPECT_CALL(*this, SuccessCallback(_, _)).Times(0);
  EXPECT_CALL(*this, FailureCallback(ConfigRef()));
  config_->ProcessEventSignal(DHCPv4Config::kReasonFail, conf);
  Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(config_->properties().address.empty());
}

TEST_F(DHCPv4ConfigCallbackTest, ProcessEventSignalSuccess) {
  for (const auto& reason : { DHCPv4Config::kReasonBound,
                              DHCPv4Config::kReasonRebind,
                              DHCPv4Config::kReasonReboot,
                              DHCPv4Config::kReasonRenew }) {
    int address_octet = 0;
    for (const auto lease_time_given : { false, true }) {
      KeyValueStore conf;
      conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, ++address_octet);
      if (lease_time_given) {
        const uint32_t kLeaseTime = 1;
        conf.SetUint(DHCPv4Config::kConfigurationKeyLeaseTime, kLeaseTime);
      }
      EXPECT_CALL(*this, SuccessCallback(ConfigRef(), true));
      EXPECT_CALL(*this, FailureCallback(_)).Times(0);
      config_->ProcessEventSignal(reason, conf);
      string failure_message = string(reason) + " failed with lease time " +
          (lease_time_given ? "given" : "not given");
      EXPECT_TRUE(Mock::VerifyAndClearExpectations(this)) << failure_message;
      EXPECT_EQ(base::StringPrintf("%d.0.0.0", address_octet),
                config_->properties().address) << failure_message;
    }
  }
}

TEST_F(DHCPv4ConfigCallbackTest, StoppedDuringFailureCallback) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  // Stop the DHCP config while it is calling the failure callback.  We
  // need to ensure that no callbacks are left running inadvertently as
  // a result.
  EXPECT_CALL(*this, FailureCallback(ConfigRef()))
      .WillOnce(InvokeWithoutArgs(this, &DHCPv4ConfigTest::StopInstance));
  config_->ProcessEventSignal(DHCPv4Config::kReasonFail, conf);
  EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
}

TEST_F(DHCPv4ConfigCallbackTest, StoppedDuringSuccessCallback) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  const uint32_t kLeaseTime = 1;
  conf.SetUint(DHCPv4Config::kConfigurationKeyLeaseTime, kLeaseTime);
  // Stop the DHCP config while it is calling the success callback.  This
  // can happen if the device has a static IP configuration and releases
  // the lease after accepting other network parameters from the DHCP
  // IPConfig properties.  We need to ensure that no callbacks are left
  // running inadvertently as a result.
  EXPECT_CALL(*this, SuccessCallback(ConfigRef(), true))
      .WillOnce(InvokeWithoutArgs(this, &DHCPv4ConfigTest::StopInstance));
  config_->ProcessEventSignal(DHCPv4Config::kReasonBound, conf);
  EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
}

TEST_F(DHCPv4ConfigCallbackTest, ProcessEventSignalUnknown) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  static const char kReasonUnknown[] = "UNKNOWN_REASON";
  EXPECT_CALL(*this, SuccessCallback(_, _)).Times(0);
  EXPECT_CALL(*this, FailureCallback(_)).Times(0);
  config_->ProcessEventSignal(kReasonUnknown, conf);
  Mock::VerifyAndClearExpectations(this);
  EXPECT_TRUE(config_->properties().address.empty());
}

TEST_F(DHCPv4ConfigCallbackTest, ProcessEventSignalGatewayArp) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  EXPECT_CALL(*this, SuccessCallback(ConfigRef(), false));
  EXPECT_CALL(*this, FailureCallback(_)).Times(0);
  EXPECT_CALL(process_manager_, StartProcessInMinijail(_, _, _, _, _, _, _))
      .WillOnce(Return(0));
  StartInstance(config_);
  config_->ProcessEventSignal(DHCPv4Config::kReasonGatewayArp, conf);
  Mock::VerifyAndClearExpectations(this);
  EXPECT_EQ("4.3.2.1", config_->properties().address);
  EXPECT_TRUE(config_->is_gateway_arp_active_);
  // Will not fail on acquisition timeout since Gateway ARP is active.
  EXPECT_FALSE(config_->ShouldFailOnAcquisitionTimeout());

  // An official reply from a DHCP server should reset our GatewayArp state.
  EXPECT_CALL(*this, SuccessCallback(ConfigRef(), true));
  EXPECT_CALL(*this, FailureCallback(_)).Times(0);
  config_->ProcessEventSignal(DHCPv4Config::kReasonRenew, conf);
  Mock::VerifyAndClearExpectations(this);
  EXPECT_FALSE(config_->is_gateway_arp_active_);
  // Will fail on acquisition timeout since Gateway ARP is not active.
  EXPECT_TRUE(config_->ShouldFailOnAcquisitionTimeout());
}

TEST_F(DHCPv4ConfigCallbackTest, ProcessEventSignalGatewayArpNak) {
  KeyValueStore conf;
  conf.SetUint(DHCPv4Config::kConfigurationKeyIPAddress, 0x01020304);
  EXPECT_CALL(process_manager_, StartProcessInMinijail(_, _, _, _, _, _, _))
      .WillOnce(Return(0));
  StartInstance(config_);
  config_->ProcessEventSignal(DHCPv4Config::kReasonGatewayArp, conf);
  EXPECT_TRUE(config_->is_gateway_arp_active_);

  // Sending a NAK should clear is_gateway_arp_active_.
  config_->ProcessEventSignal(DHCPv4Config::kReasonNak, conf);
  EXPECT_FALSE(config_->is_gateway_arp_active_);
  // Will fail on acquisition timeout since Gateway ARP is not active.
  EXPECT_TRUE(config_->ShouldFailOnAcquisitionTimeout());
  Mock::VerifyAndClearExpectations(this);
}

TEST_F(DHCPv4ConfigTest, ProcessStatusChangeSingal) {
  EXPECT_CALL(metrics_, NotifyDhcpClientStatus(
      Metrics::kDhcpClientStatusBound));
  config_->ProcessStatusChangeSignal(DHCPv4Config::kStatusBound);
}

TEST_F(DHCPv4ConfigTest, StartSuccessEphemeral) {
  DHCPv4ConfigRefPtr config =
      CreateRunningConfig(kHostName, kVendorClass, kDeviceName, kArpGateway);
  StopRunningConfigAndExpect(config, false);
}

TEST_F(DHCPv4ConfigTest, StartSuccessPersistent) {
  DHCPv4ConfigRefPtr config =
      CreateRunningConfig(kHostName, kVendorClass,
                          kLeaseFileSuffix, kArpGateway);
  StopRunningConfigAndExpect(config, true);
}

}  // namespace shill
