// 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 <gtest/gtest.h>

#include "shill/logging.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_client_test_helper.h"
#include "shill/net/arp_packet.h"
#include "shill/net/byte_string.h"
#include "shill/net/ip_address.h"
#include "shill/net/mock_arp_client.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::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))) {}
  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_;

  DISALLOW_COPY_AND_ASSIGN(ActiveLinkMonitorObserver);
};

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, arraysize(kRemoteMacAddress)),
        local_mac_(kLocalMacAddress, arraysize(kLocalMacAddress)),
        zero_mac_(arraysize(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_, PostTask(_, _)).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::LOG_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::LOG_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::LOG_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::LOG_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::LOG_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(arraysize(kSamples));
  ASSERT_GT(arraysize(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 < arraysize(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, arraysize(address0))));
  const uint8_t address1[] = {0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd};
  EXPECT_EQ("88:99:aa:bb:cc:dd",
            HardwareAddressToString(ByteString(address1, arraysize(address1))));
}

}  // namespace shill
