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

#include <net/if_arp.h>

#include <string>

#include <base/bind.h>
#include <base/stl_util.h>
#include <gtest/gtest.h>

#include "shill/arp_client_test_helper.h"
#include "shill/logging.h"
#include "shill/mock_arp_client.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_log.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/net/arp_packet.h"
#include "shill/net/byte_string.h"
#include "shill/net/ip_address.h"
#include "shill/net/mock_io_handler_factory.h"
#include "shill/net/mock_sockets.h"
#include "shill/net/mock_time.h"

using base::Bind;
using base::Unretained;
using std::string;
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
using testing::HasSubstr;
using testing::Mock;
using testing::NiceMock;
using testing::Return;
using testing::ReturnRef;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::Test;

namespace shill {

namespace {
const char kInterfaceName[] = "int0";
const char kLocalIPAddress[] = "10.0.1.1";
const uint8_t kLocalMacAddress[] = {0, 1, 2, 3, 4, 5};
const char kRemoteIPAddress[] = "10.0.1.2";
const uint8_t kRemoteMacAddress[] = {6, 7, 8, 9, 10, 11};
const RpcIdentifier kDBusPath("/dbus/path");
}  // namespace

class ActiveLinkMonitorObserver {
 public:
  ActiveLinkMonitorObserver()
      : failure_callback_(Bind(&ActiveLinkMonitorObserver::OnFailureCallback,
                               Unretained(this))),
        success_callback_(Bind(&ActiveLinkMonitorObserver::OnSuccessCallback,
                               Unretained(this))) {}
  ActiveLinkMonitorObserver(const ActiveLinkMonitorObserver&) = delete;
  ActiveLinkMonitorObserver& operator=(const ActiveLinkMonitorObserver&) =
      delete;

  virtual ~ActiveLinkMonitorObserver() = default;

  MOCK_METHOD(void, OnFailureCallback, (Metrics::LinkMonitorFailure, int, int));
  MOCK_METHOD(void, OnSuccessCallback, ());

  const ActiveLinkMonitor::FailureCallback failure_callback() const {
    return failure_callback_;
  }

  const ActiveLinkMonitor::SuccessCallback success_callback() const {
    return success_callback_;
  }

 private:
  ActiveLinkMonitor::FailureCallback failure_callback_;
  ActiveLinkMonitor::SuccessCallback success_callback_;
};

MATCHER_P4(IsArpRequest, local_ip, remote_ip, local_mac, remote_mac, "") {
  if (local_ip.Equals(arg.local_ip_address()) &&
      remote_ip.Equals(arg.remote_ip_address()) &&
      local_mac.Equals(arg.local_mac_address()) &&
      remote_mac.Equals(arg.remote_mac_address()))
    return true;

  if (!local_ip.Equals(arg.local_ip_address())) {
    *result_listener << "Local IP '" << arg.local_ip_address().ToString()
                     << "' (wanted '" << local_ip.ToString() << "').";
  }

  if (!remote_ip.Equals(arg.remote_ip_address())) {
    *result_listener << "Remote IP '" << arg.remote_ip_address().ToString()
                     << "' (wanted '" << remote_ip.ToString() << "').";
  }

  if (!local_mac.Equals(arg.local_mac_address())) {
    *result_listener << "Local MAC '" << arg.local_mac_address().HexEncode()
                     << "' (wanted " << local_mac.HexEncode() << ")'.";
  }

  if (!remote_mac.Equals(arg.remote_mac_address())) {
    *result_listener << "Remote MAC '" << arg.remote_mac_address().HexEncode()
                     << "' (wanted " << remote_mac.HexEncode() << ")'.";
  }

  return false;
}

class ActiveLinkMonitorTest : public Test {
 public:
  ActiveLinkMonitorTest()
      : manager_(&control_, &dispatcher_, &metrics_),
        device_info_(&manager_),
        connection_(new StrictMock<MockConnection>(&device_info_)),
        client_(new MockArpClient()),
        client_test_helper_(client_),
        gateway_ip_(IPAddress::kFamilyIPv4),
        local_ip_(IPAddress::kFamilyIPv4),
        gateway_mac_(kRemoteMacAddress, base::size(kRemoteMacAddress)),
        local_mac_(kLocalMacAddress, base::size(kLocalMacAddress)),
        zero_mac_(base::size(kLocalMacAddress)),
        link_scope_logging_was_enabled_(false),
        interface_name_(kInterfaceName),
        monitor_(connection_,
                 &dispatcher_,
                 &metrics_,
                 &device_info_,
                 observer_.failure_callback(),
                 observer_.success_callback()) {
    monitor_.io_handler_factory_ = &io_handler_factory_;
  }

  ~ActiveLinkMonitorTest() override = default;

  void SetUp() override {
    link_scope_logging_was_enabled_ = SLOG_IS_ON(Link, 0);
    if (!link_scope_logging_was_enabled_) {
      ScopeLogger::GetInstance()->EnableScopesByName("link");
      ScopeLogger::GetInstance()->set_verbose_level(4);
    }
    monitor_.arp_client_.reset(client_);
    monitor_.time_ = &time_;
    time_val_.tv_sec = 0;
    time_val_.tv_usec = 0;
    EXPECT_CALL(time_, GetTimeMonotonic(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(time_val_), Return(0)));
    EXPECT_TRUE(local_ip_.SetAddressFromString(kLocalIPAddress));
    EXPECT_CALL(*connection_, local()).WillRepeatedly(ReturnRef(local_ip_));
    EXPECT_TRUE(gateway_ip_.SetAddressFromString(kRemoteIPAddress));
    EXPECT_CALL(*connection_, gateway()).WillRepeatedly(ReturnRef(gateway_ip_));
    EXPECT_CALL(*connection_, technology())
        .WillRepeatedly(Return(Technology::kEthernet));
    EXPECT_CALL(*connection_, ipconfig_rpc_identifier())
        .WillRepeatedly(testing::ReturnPointee(&kDBusPath));
    EXPECT_CALL(*connection_, interface_name())
        .WillRepeatedly(ReturnRef(interface_name_));
  }

  void TearDown() override {
    if (!link_scope_logging_was_enabled_) {
      ScopeLogger::GetInstance()->EnableScopesByName("-link");
      ScopeLogger::GetInstance()->set_verbose_level(0);
    }
  }

  void AdvanceTime(int time_ms) {
    struct timeval adv_time = {static_cast<time_t>(time_ms / 1000),
                               static_cast<time_t>((time_ms % 1000) * 1000)};
    timeradd(&time_val_, &adv_time, &time_val_);
    EXPECT_CALL(time_, GetTimeMonotonic(_))
        .WillRepeatedly(DoAll(SetArgPointee<0>(time_val_), Return(0)));
  }

  string HardwareAddressToString(const ByteString& address) {
    return ActiveLinkMonitor::HardwareAddressToString(address);
  }

 protected:
  void ExpectReset() {
    EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
    EXPECT_TRUE(GetSendRequestCallback().IsCancelled());
    EXPECT_EQ(0, GetBroadcastFailureCount());
    EXPECT_EQ(0, GetUnicastFailureCount());
    EXPECT_EQ(0, GetBroadcastSuccessCount());
    EXPECT_EQ(0, GetUnicastSuccessCount());
    EXPECT_FALSE(IsUnicast());
    EXPECT_FALSE(GatewaySupportsUnicastArp());
  }
  void TriggerRequestTimer() { GetSendRequestCallback().callback().Run(); }
  const base::CancelableClosure& GetSendRequestCallback() {
    return monitor_.send_request_callback_;
  }
  int GetBroadcastFailureCount() { return monitor_.broadcast_failure_count_; }
  int GetUnicastFailureCount() { return monitor_.unicast_failure_count_; }
  int GetBroadcastSuccessCount() { return monitor_.broadcast_success_count_; }
  int GetUnicastSuccessCount() { return monitor_.unicast_success_count_; }
  bool IsUnicast() { return monitor_.is_unicast_; }
  bool GatewaySupportsUnicastArp() {
    return monitor_.gateway_supports_unicast_arp_;
  }
  int GetCurrentTestPeriodMilliseconds() {
    return monitor_.test_period_milliseconds_;
  }
  int GetDefaultTestPeriodMilliseconds() {
    return ActiveLinkMonitor::kDefaultTestPeriodMilliseconds;
  }
  size_t GetFailureThreshold() { return ActiveLinkMonitor::kFailureThreshold; }
  size_t GetUnicastReplyReliabilityThreshold() {
    return ActiveLinkMonitor::kUnicastReplyReliabilityThreshold;
  }
  int GetFastTestPeriodMilliseconds() {
    return ActiveLinkMonitor::kFastTestPeriodMilliseconds;
  }
  int GetMaxResponseSampleFilterDepth() {
    return ActiveLinkMonitor::kMaxResponseSampleFilterDepth;
  }
  void ExpectTransmit(bool is_unicast, int transmit_period_milliseconds) {
    const ByteString& destination_mac = is_unicast ? gateway_mac_ : zero_mac_;
    EXPECT_CALL(*client_,
                TransmitRequest(IsArpRequest(local_ip_, gateway_ip_, local_mac_,
                                             destination_mac)))
        .WillOnce(Return(true));
    EXPECT_CALL(dispatcher_,
                PostDelayedTask(_, _, transmit_period_milliseconds));
  }
  void SendNextRequest() {
    EXPECT_CALL(*client_, TransmitRequest(_)).WillOnce(Return(true));
    EXPECT_CALL(dispatcher_,
                PostDelayedTask(_, _, GetCurrentTestPeriodMilliseconds()));
    TriggerRequestTimer();
  }
  void ExpectNoTransmit() {
    EXPECT_CALL(*client_, TransmitRequest(_)).Times(0);
  }
  void StartMonitor() {
    EXPECT_CALL(device_info_, GetMacAddress(0, _))
        .WillOnce(DoAll(SetArgPointee<1>(local_mac_), Return(true)));
    EXPECT_CALL(*client_, StartReplyListener()).WillOnce(Return(true));
    EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, 0)).Times(1);
    EXPECT_TRUE(
        monitor_.Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
    EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
  }
  void ReceiveResponse(uint16_t operation,
                       const IPAddress& local_ip,
                       const ByteString& local_mac,
                       const IPAddress& remote_ip,
                       const ByteString& remote_mac) {
    client_test_helper_.GeneratePacket(operation, local_ip, local_mac,
                                       remote_ip, remote_mac);
    monitor_.ReceiveResponse(0);
  }
  void ReceiveCorrectResponse() {
    ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_, local_ip_,
                    local_mac_);
  }
  void ReceiveReplyAndRestartMonitorCycle() {
    EXPECT_CALL(observer_, OnSuccessCallback()).Times(1);
    ReceiveCorrectResponse();
    Mock::VerifyAndClearExpectations(&observer_);
    StartMonitor();
  }
  void RunUnicastResponseCycle(int cycle_count,
                               bool should_respond_to_unicast_probes,
                               bool should_count_failures) {
    // This method expects the ActiveLinkMonitor to be in a state where it
    // is waiting for a broadcast response.  It also returns with the
    // ActiveLinkMonitor in the same state.
    // Successful receptions.
    EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"),
                                    0, _, _, _))
        .Times(cycle_count * (should_respond_to_unicast_probes ? 2 : 1));
    // Unsuccessful unicast receptions.
    EXPECT_CALL(metrics_,
                SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"),
                          GetDefaultTestPeriodMilliseconds(), _, _, _))
        .Times(cycle_count * (should_respond_to_unicast_probes ? 0 : 1));

    // Account for any successes / failures before we started.
    int expected_broadcast_success_count = GetBroadcastSuccessCount();
    int expected_unicast_success_count = GetUnicastSuccessCount();
    int expected_unicast_failure_count = GetUnicastFailureCount();

    LOG(INFO) << "RunUnicastResponseCycle: " << cycle_count;

    for (int i = 0; i < cycle_count; ++i) {
      // Respond to the pending broadcast request.
      ReceiveReplyAndRestartMonitorCycle();

      // Unicast ARP.
      ExpectTransmit(true, GetDefaultTestPeriodMilliseconds());
      TriggerRequestTimer();
      if (should_respond_to_unicast_probes) {
        ReceiveReplyAndRestartMonitorCycle();
      }

      // Initiate broadcast ARP.
      ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
      TriggerRequestTimer();

      ++expected_broadcast_success_count;
      if (should_respond_to_unicast_probes) {
        ++expected_unicast_success_count;
        expected_unicast_failure_count = 0;
      } else {
        if (should_count_failures) {
          ++expected_unicast_failure_count;
        }
        expected_unicast_success_count = 0;
      }
      EXPECT_EQ(expected_unicast_failure_count, GetUnicastFailureCount());
      EXPECT_EQ(expected_unicast_success_count, GetUnicastSuccessCount());
      EXPECT_EQ(0, GetBroadcastFailureCount());
      EXPECT_EQ(expected_broadcast_success_count, GetBroadcastSuccessCount());
    }
  }

  MockEventDispatcher dispatcher_;
  StrictMock<MockMetrics> metrics_;
  MockControl control_;
  MockManager manager_;
  NiceMock<MockDeviceInfo> device_info_;
  scoped_refptr<MockConnection> connection_;
  MockTime time_;
  struct timeval time_val_;
  // This is owned by the LinkMonitor, and only tracked here for EXPECT*().
  MockArpClient* client_;
  ArpClientTestHelper client_test_helper_;
  ActiveLinkMonitorObserver observer_;
  IPAddress gateway_ip_;
  IPAddress local_ip_;
  ByteString gateway_mac_;
  ByteString local_mac_;
  ByteString zero_mac_;
  bool link_scope_logging_was_enabled_;
  const string interface_name_;
  MockIOHandlerFactory io_handler_factory_;
  ActiveLinkMonitor monitor_;
};

TEST_F(ActiveLinkMonitorTest, Constructor) {
  ExpectReset();
}

TEST_F(ActiveLinkMonitorTest, StartFailedGetMacAddress) {
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
                       HasSubstr("Could not get local MAC address")))
      .Times(1);
  EXPECT_CALL(device_info_, GetMacAddress(0, _)).WillOnce(Return(false));
  EXPECT_CALL(metrics_,
              SendEnumToUMA(HasSubstr("LinkMonitorFailure"),
                            Metrics::kLinkMonitorMacAddressNotFound, _));
  EXPECT_CALL(*client_, StartReplyListener()).Times(0);
  EXPECT_FALSE(
      monitor_.Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
  ExpectReset();
}

TEST_F(ActiveLinkMonitorTest, StartFailedArpClient) {
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
                       HasSubstr("Failed to start ARP client")))
      .Times(1);
  EXPECT_CALL(metrics_,
              SendEnumToUMA(HasSubstr("LinkMonitorFailure"),
                            Metrics::kLinkMonitorClientStartFailure, _));
  EXPECT_CALL(device_info_, GetMacAddress(0, _)).WillOnce(Return(true));
  EXPECT_CALL(*client_, StartReplyListener()).WillOnce(Return(false));
  EXPECT_FALSE(
      monitor_.Start(ActiveLinkMonitor::kDefaultTestPeriodMilliseconds));
  ExpectReset();
}

TEST_F(ActiveLinkMonitorTest, StartSuccess) {
  StartMonitor();
}

TEST_F(ActiveLinkMonitorTest, Stop) {
  StartMonitor();
  EXPECT_CALL(*client_, Stop()).Times(1);
  monitor_.Stop();
  ExpectReset();
  Mock::VerifyAndClearExpectations(client_);
}

TEST_F(ActiveLinkMonitorTest, ReplyReception) {
  StartMonitor();
  const int kResponseTime = 1234;
  AdvanceTime(kResponseTime);
  ScopedMockLog log;

  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, HasSubstr("not for our IP"))).Times(1);
  ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_, gateway_ip_,
                  local_mac_);
  Mock::VerifyAndClearExpectations(&log);

  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, HasSubstr("not for our MAC"))).Times(1);
  ReceiveResponse(ARPOP_REPLY, gateway_ip_, gateway_mac_, local_ip_,
                  gateway_mac_);
  Mock::VerifyAndClearExpectations(&log);

  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, HasSubstr("not from the gateway"))).Times(1);
  ReceiveResponse(ARPOP_REPLY, local_ip_, gateway_mac_, local_ip_, local_mac_);
  Mock::VerifyAndClearExpectations(&log);

  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, HasSubstr("This is not a reply packet"))).Times(1);
  ReceiveResponse(ARPOP_REQUEST, gateway_ip_, gateway_mac_, local_ip_,
                  local_mac_);
  Mock::VerifyAndClearExpectations(&log);

  EXPECT_FALSE(monitor_.GetResponseTimeMilliseconds());
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(_, _, HasSubstr("Found gateway"))).Times(1);
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"),
                                  kResponseTime, _, _, _))
      .Times(1);
  EXPECT_CALL(*client_, Stop()).Times(1);
  EXPECT_CALL(observer_, OnSuccessCallback()).Times(1);
  ReceiveCorrectResponse();
  EXPECT_EQ(kResponseTime, monitor_.GetResponseTimeMilliseconds());
  EXPECT_TRUE(IsUnicast());
  Mock::VerifyAndClearExpectations(client_);
}

TEST_F(ActiveLinkMonitorTest, TimeoutBroadcast) {
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"),
                                  GetDefaultTestPeriodMilliseconds(), _, _, _))
      .Times(GetFailureThreshold());
  StartMonitor();
  // This value doesn't match real life (the timer in this scenario
  // should advance by ActiveLinkMonitor::kDefaultTestPeriodMilliseconds),
  // but this demonstrates the LinkMonitorSecondsToFailure independent
  // from the response-time figures.
  const int kTimeIncrement = 1000;
  // Transmit initial request.
  ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
  AdvanceTime(kTimeIncrement);
  TriggerRequestTimer();
  for (size_t i = 1; i < GetFailureThreshold(); ++i) {
    ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
    AdvanceTime(kTimeIncrement);
    TriggerRequestTimer();
    EXPECT_FALSE(IsUnicast());
    EXPECT_EQ(i, GetBroadcastFailureCount());
    EXPECT_EQ(0, GetUnicastFailureCount());
    EXPECT_EQ(0, GetBroadcastSuccessCount());
    EXPECT_EQ(0, GetUnicastSuccessCount());
    EXPECT_EQ(GetDefaultTestPeriodMilliseconds(),
              monitor_.GetResponseTimeMilliseconds());
  }
  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
                       HasSubstr("monitor has reached the failure threshold")))
      .Times(1);
  EXPECT_CALL(observer_,
              OnFailureCallback(Metrics::kLinkMonitorFailureThresholdReached,
                                GetFailureThreshold(), 0))
      .Times(1);
  EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
  // Transmit final request.
  ExpectNoTransmit();
  AdvanceTime(kTimeIncrement);
  TriggerRequestTimer();
  ExpectReset();
}

TEST_F(ActiveLinkMonitorTest, TimeoutUnicast) {
  StartMonitor();

  // Setup expectation for Time::GetTimeMonotonic.
  const int kTimeIncrement = 1000;
  AdvanceTime(kTimeIncrement);
  // Initiate a broadcast ARP.
  ExpectTransmit(false, GetDefaultTestPeriodMilliseconds());
  TriggerRequestTimer();

  ScopedMockLog log;
  EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
  EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
                       HasSubstr("monitor has reached the failure threshold")))
      .Times(0);

  // Unicast failures should not cause LinkMonitor errors if we haven't
  // noted the gateway as reliably replying to unicast ARP messages.  Test
  // this by doing threshold - 1 successful unicast responses, followed
  // by a ton of unicast failures.
  // Initiate broadcast ARP.
  RunUnicastResponseCycle(GetUnicastReplyReliabilityThreshold() - 1, true,
                          false);
  EXPECT_EQ(GetUnicastReplyReliabilityThreshold() - 1,
            GetUnicastSuccessCount());
  RunUnicastResponseCycle(
      GetFailureThreshold() + GetUnicastReplyReliabilityThreshold(), false,
      false);
  EXPECT_FALSE(GetSendRequestCallback().IsCancelled());
  EXPECT_FALSE(GatewaySupportsUnicastArp());
  EXPECT_EQ(0, GetUnicastSuccessCount());
  EXPECT_EQ(0, GetUnicastFailureCount());

  // Cross the the unicast reliability threshold.
  RunUnicastResponseCycle(GetUnicastReplyReliabilityThreshold() - 1, true,
                          false);
  EXPECT_CALL(log, Log(_, _, HasSubstr("Unicast failures will now count")));
  EXPECT_FALSE(GatewaySupportsUnicastArp());
  RunUnicastResponseCycle(1, true, false);
  EXPECT_TRUE(GatewaySupportsUnicastArp());

  // Induce one less failures than will cause a link monitor failure, and
  // confirm that these failures are counted.
  RunUnicastResponseCycle(GetFailureThreshold() - 1, false, true);
  EXPECT_EQ(GetFailureThreshold() - 1, GetUnicastFailureCount());

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

  // Induce a final broadcast success followed by a unicast failure.
  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"), 0,
                                  _, _, _));
  ReceiveReplyAndRestartMonitorCycle();

  ExpectTransmit(true, GetDefaultTestPeriodMilliseconds());
  TriggerRequestTimer();
  EXPECT_FALSE(GetSendRequestCallback().IsCancelled());

  EXPECT_CALL(metrics_, SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"),
                                  GetDefaultTestPeriodMilliseconds(), _, _, _));
  EXPECT_CALL(log, Log(logging::LOGGING_ERROR, _,
                       HasSubstr("monitor has reached the failure threshold")))
      .Times(1);
  EXPECT_CALL(observer_,
              OnFailureCallback(Metrics::kLinkMonitorFailureThresholdReached, 0,
                                GetFailureThreshold()))
      .Times(1);
  ExpectNoTransmit();
  TriggerRequestTimer();
  ExpectReset();
}

TEST_F(ActiveLinkMonitorTest, Average) {
  const int kSamples[] = {200, 950, 1200, 4096, 5000, 86, 120, 3060, 842, 750};
  const size_t filter_depth = GetMaxResponseSampleFilterDepth();
  EXPECT_CALL(metrics_,
              SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
      .Times(base::size(kSamples));
  ASSERT_GT(base::size(kSamples), filter_depth);
  StartMonitor();
  size_t i = 0;
  int sum = 0;
  for (; i < filter_depth; ++i) {
    AdvanceTime(kSamples[i]);
    ReceiveReplyAndRestartMonitorCycle();
    sum += kSamples[i];
    EXPECT_EQ(sum / (i + 1), monitor_.GetResponseTimeMilliseconds());
    SendNextRequest();
  }
  for (; i < base::size(kSamples); ++i) {
    AdvanceTime(kSamples[i]);
    ReceiveReplyAndRestartMonitorCycle();
    sum = (sum + kSamples[i]) * filter_depth / (filter_depth + 1);
    EXPECT_EQ(sum / filter_depth, monitor_.GetResponseTimeMilliseconds());
    SendNextRequest();
  }
}

TEST_F(ActiveLinkMonitorTest, ImpulseResponse) {
  const int kNormalValue = 50;
  const int kExceptionalValue = 5000;
  const int filter_depth = GetMaxResponseSampleFilterDepth();
  EXPECT_CALL(metrics_,
              SendToUMA(HasSubstr("LinkMonitorResponseTimeSample"), _, _, _, _))
      .Times(AnyNumber());
  StartMonitor();
  for (int i = 0; i < filter_depth * 2; ++i) {
    AdvanceTime(kNormalValue);
    ReceiveReplyAndRestartMonitorCycle();
    EXPECT_EQ(kNormalValue, monitor_.GetResponseTimeMilliseconds());
    SendNextRequest();
  }
  AdvanceTime(kExceptionalValue);
  ReceiveReplyAndRestartMonitorCycle();
  // Our expectation is that an impulse input will be a
  // impulse_height / (filter_depth + 1) increase to the running average.
  int expected_impulse_response =
      kNormalValue + (kExceptionalValue - kNormalValue) / (filter_depth + 1);
  EXPECT_EQ(expected_impulse_response, monitor_.GetResponseTimeMilliseconds());
  SendNextRequest();

  // From here, if we end up continuing to receive normal values, our
  // running average should decay backwards to the normal value.
  const int failsafe = 100;
  int last_value = monitor_.GetResponseTimeMilliseconds();
  for (int i = 0; i < failsafe && last_value != kNormalValue; ++i) {
    AdvanceTime(kNormalValue);
    ReceiveReplyAndRestartMonitorCycle();
    // We should advance monotonically (but not necessarily linearly)
    // back towards the normal value.
    EXPECT_GE(last_value, monitor_.GetResponseTimeMilliseconds());
    SendNextRequest();
    last_value = monitor_.GetResponseTimeMilliseconds();
  }
  EXPECT_EQ(kNormalValue, last_value);
}

TEST_F(ActiveLinkMonitorTest, HardwareAddressToString) {
  const uint8_t address0[] = {0, 1, 2, 3, 4, 5};
  EXPECT_EQ("00:01:02:03:04:05", HardwareAddressToString(ByteString(
                                     address0, base::size(address0))));
  const uint8_t address1[] = {0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd};
  EXPECT_EQ("88:99:aa:bb:cc:dd", HardwareAddressToString(ByteString(
                                     address1, base::size(address1))));
}

}  // namespace shill
