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

#include <base/test/simple_test_tick_clock.h>
#include <gtest/gtest.h>

#include "shill/mock_event_dispatcher.h"
#include "shill/mock_icmp.h"
#include "shill/net/ip_address.h"

using base::Bind;
using base::Unretained;
using testing::_;
using testing::NiceMock;
using testing::Return;
using testing::StrictMock;
using testing::Test;

namespace shill {

namespace {

// Note: this IPv4 header is given in network byte order, since
// IcmpSession::OnEchoReplyReceived expects to receive a raw IP packet.
const uint8_t kIpHeader[] = {0x45, 0x80, 0x00, 0x1c, 0x63, 0xd3, 0x00,
                             0x00, 0x39, 0x01, 0xcc, 0x9f, 0x4a, 0x7d,
                             0xe0, 0x18, 0x64, 0x6e, 0xc1, 0xea};
// ICMPv4 echo replies with 0 bytes of data and and echo ID 0. Sequence numbers
// are 0x8, 0x9, and 0xa respectively to simulate replies to a sequence of sent
// echo requests.  Note that these only match on little-endian hosts.
const uint8_t kIcmpEchoReply1[] = {0x00, 0x00, 0xf7, 0xff,
                                   0x00, 0x00, 0x08, 0x00};
const uint16_t kIcmpEchoReply1_SeqNum = 0x08;
const uint8_t kIcmpEchoReply2[] = {0x00, 0x00, 0xf6, 0xff,
                                   0x00, 0x00, 0x09, 0x00};
const uint16_t kIcmpEchoReply2_SeqNum = 0x09;
const uint8_t kIcmpEchoReply3[] = {0x00, 0x00, 0xf5, 0xff,
                                   0x00, 0x00, 0x0a, 0x00};
const uint16_t kIcmpEchoReply3_SeqNum = 0x0a;

// ICMPv6 echo reply with 0 bytes of data, echo ID 0, and sequence number 0x8.
const uint8_t kIcmpV6EchoReply1[] = {
    0x81, 0x00, 0x76, 0xff, 0x00, 0x00, 0x08, 0x00};

// This ICMPv4 echo reply has an echo ID of 0xe, which is different from the
// echo ID used in the unit tests (0).
const uint8_t kIcmpEchoReplyDifferentEchoID[] = {0x00, 0x00, 0xea, 0xff,
                                                 0x0e, 0x00, 0x0b, 0x00};

}  // namespace

MATCHER_P(IsIPAddress, address, "") {
  // IPAddress objects don't support the "==" operator as per style, so we need
  // a custom matcher.
  return address.Equals(arg);
}

class IcmpSessionTest : public Test {
 public:
  IcmpSessionTest() : icmp_session_(&dispatcher_) {}
  virtual ~IcmpSessionTest() {}

  virtual void SetUp() {
    icmp_session_.tick_clock_ = &testing_clock_;
    icmp_ = new NiceMock<MockIcmp>();
    // Passes ownership.
    icmp_session_.icmp_.reset(icmp_);
    ON_CALL(*icmp_, IsStarted()).WillByDefault(Return(false));
  }

  virtual void TearDown() {
    EXPECT_CALL(*icmp_, IsStarted());
    IcmpSession::kNextUniqueEchoId = 0;
  }

  MOCK_METHOD1(ResultCallback, void(const IcmpSession::IcmpSessionResult&));

 protected:
  static const char kIPAddress[];
  static const char kIP6Address[];
  static const int kInterfaceIndex;

  void StartAndVerify(const IPAddress& destination, int interface_index) {
    EXPECT_CALL(*icmp_, IsStarted());
    EXPECT_CALL(*icmp_, Start(IsIPAddress(destination), interface_index))
        .WillOnce(Return(true));
    icmp_->destination_ = destination;
    EXPECT_CALL(dispatcher_, CreateInputHandler(icmp_->socket(), _, _));
    EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, GetTimeoutSeconds() * 1000));
    EXPECT_CALL(dispatcher_, PostTask(_, _));
    EXPECT_TRUE(Start(destination, interface_index));
    EXPECT_TRUE(GetSeqNumToSentRecvTime()->empty());
    EXPECT_TRUE(GetReceivedEchoReplySeqNumbers()->empty());
    EXPECT_CALL(*icmp_, IsStarted()).WillRepeatedly(Return(true));
  }

  bool Start(const IPAddress& destination, int interface_index) {
    return icmp_session_.Start(
        destination,
        interface_index,
        Bind(&IcmpSessionTest::ResultCallback, Unretained(this)));
  }

  void Stop() {
    icmp_session_.Stop();
  }

  bool SeqNumToSentRecvTimeContains(uint16_t seq_num) {
    return icmp_session_.seq_num_to_sent_recv_time_.find(seq_num) !=
           icmp_session_.seq_num_to_sent_recv_time_.end();
  }

  bool ReceivedEchoReplySeqNumbersContains(uint16_t seq_num) {
    return icmp_session_.received_echo_reply_seq_numbers_.find(seq_num) !=
           icmp_session_.received_echo_reply_seq_numbers_.end();
  }

  void TransmitEchoRequestTask(bool transmit_request_success) {
    EXPECT_CALL(
        *icmp_,
        TransmitEchoRequest(icmp_session_.echo_id_, GetCurrentSequenceNumber()))
        .WillOnce(Return(transmit_request_success));
    icmp_session_.TransmitEchoRequestTask();
  }

  void ReportResultAndStopSession() {
    icmp_session_.ReportResultAndStopSession();
  }

  void VerifyIcmpSessionStopped() {
    EXPECT_TRUE(icmp_session_.timeout_callback_.IsCancelled());
    EXPECT_FALSE(icmp_session_.echo_reply_handler_);
  }

  void OnEchoReplyReceived(InputData* data) {
    icmp_session_.OnEchoReplyReceived(data);
  }

  IcmpSession::IcmpSessionResult GenerateIcmpResult() {
    return icmp_session_.GenerateIcmpResult();
  }

  std::map<uint16_t, IcmpSession::SentRecvTimePair>* GetSeqNumToSentRecvTime() {
    return &icmp_session_.seq_num_to_sent_recv_time_;
  }
  std::set<uint16_t>* GetReceivedEchoReplySeqNumbers() {
    return &icmp_session_.received_echo_reply_seq_numbers_;
  }
  uint16_t GetNextUniqueEchoId() const {
    return IcmpSession::kNextUniqueEchoId;
  }
  int GetTotalNumEchoRequests() const {
    return IcmpSession::kTotalNumEchoRequests;
  }
  int GetCurrentSequenceNumber() const {
    return icmp_session_.current_sequence_number_;
  }
  void SetCurrentSequenceNumber(uint16_t val) {
    icmp_session_.current_sequence_number_ = val;
  }
  size_t GetTimeoutSeconds() const { return IcmpSession::kTimeoutSeconds; }
  int GetEchoRequestIntervalSeconds() const {
    return IcmpSession::kEchoRequestIntervalSeconds;
  }

  MockIcmp* icmp_;
  StrictMock<MockEventDispatcher> dispatcher_;
  IcmpSession icmp_session_;
  base::SimpleTestTickClock testing_clock_;
};

const char IcmpSessionTest::kIPAddress[] = "10.0.1.1";
const char IcmpSessionTest::kIP6Address[] = "2001:db8::1234:5678";
const int IcmpSessionTest::kInterfaceIndex = 3;

TEST_F(IcmpSessionTest, Constructor) {
  // |icmp_session_| should have been assigned the value of |kNextUniqueEchoId|
  // on construction, and caused the value of this static variable to be
  // incremented.
  uint16_t saved_echo_id = GetNextUniqueEchoId();
  EXPECT_EQ(saved_echo_id - 1, icmp_session_.echo_id_);

  // The next IcmpSession object constructed, |session| should get the next
  // unique value of |kNextUniqueEchoId|, and further increment this variable.
  IcmpSession session(&dispatcher_);
  EXPECT_EQ(saved_echo_id, session.echo_id_);
  EXPECT_EQ(saved_echo_id + 1, GetNextUniqueEchoId());
}

TEST_F(IcmpSessionTest, StartWhileAlreadyStarted) {
  IPAddress ipv4_destination(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ipv4_destination.SetAddressFromString(kIPAddress));
  StartAndVerify(ipv4_destination, kInterfaceIndex);

  // Since an ICMP session is already started, we should fail to start it again.
  EXPECT_CALL(*icmp_, Start(IsIPAddress(ipv4_destination), kInterfaceIndex))
      .Times(0);
  EXPECT_CALL(dispatcher_, CreateInputHandler(_, _, _)).Times(0);
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, _)).Times(0);
  EXPECT_CALL(dispatcher_, PostTask(_, _)).Times(0);
  EXPECT_FALSE(Start(ipv4_destination, kInterfaceIndex));
}

TEST_F(IcmpSessionTest, StopWhileNotStarted) {
  // Attempting to stop the ICMP session while it is not started should do
  // nothing.
  EXPECT_CALL(*icmp_, IsStarted()).WillOnce(Return(false));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  EXPECT_CALL(*icmp_, Stop()).Times(0);
  Stop();
}

TEST_F(IcmpSessionTest, SessionSuccess) {
  // Test a successful ICMP session where the sending of requests and receiving
  // of replies are interleaved. Moreover, test the case where transmitting an
  // echo request fails.

  base::TimeTicks now = testing_clock_.NowTicks();
  base::TimeTicks kSentTime1 = base::TimeTicks::FromInternalValue(10);
  base::TimeTicks kRecvTime1 = base::TimeTicks::FromInternalValue(20);
  base::TimeTicks kSentTime2 = base::TimeTicks::FromInternalValue(30);
  base::TimeTicks kSentTime3 = base::TimeTicks::FromInternalValue(40);
  base::TimeTicks kRecvTime2 = base::TimeTicks::FromInternalValue(50);
  base::TimeTicks kWrongEchoIDRecvTime = base::TimeTicks::FromInternalValue(60);
  base::TimeTicks kRecvTime3 = base::TimeTicks::FromInternalValue(70);

  IcmpSession::IcmpSessionResult expected_result;
  expected_result.push_back(kRecvTime1 - kSentTime1);
  expected_result.push_back(kRecvTime2 - kSentTime2);
  expected_result.push_back(kRecvTime3 - kSentTime3);

  // Initiate session.
  IPAddress ipv4_destination(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ipv4_destination.SetAddressFromString(kIPAddress));
  StartAndVerify(ipv4_destination, kInterfaceIndex);

  // Send the first echo request.
  testing_clock_.Advance(kSentTime1 - now);
  now = testing_clock_.NowTicks();
  SetCurrentSequenceNumber(kIcmpEchoReply1_SeqNum);
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(true);
  EXPECT_TRUE(GetReceivedEchoReplySeqNumbers()->empty());
  EXPECT_EQ(1, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply1_SeqNum));
  EXPECT_EQ(now, GetSeqNumToSentRecvTime()->at(kIcmpEchoReply1_SeqNum).first);
  EXPECT_EQ(kIcmpEchoReply2_SeqNum, GetCurrentSequenceNumber());

  // Receive first reply.
  testing_clock_.Advance(kRecvTime1 - now);
  now = testing_clock_.NowTicks();
  uint8_t buffer_1[sizeof(kIpHeader) + sizeof(kIcmpEchoReply1)];
  memcpy(buffer_1, kIpHeader, sizeof(kIpHeader));
  memcpy(buffer_1 + sizeof(kIpHeader), kIcmpEchoReply1,
         sizeof(kIcmpEchoReply1));
  InputData data_1(reinterpret_cast<unsigned char*>(buffer_1),
                   sizeof(buffer_1));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  OnEchoReplyReceived(&data_1);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_TRUE(ReceivedEchoReplySeqNumbersContains(kIcmpEchoReply1_SeqNum));

  // Send the second echo request.
  testing_clock_.Advance(kSentTime2 - now);
  now = testing_clock_.NowTicks();
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(true);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_EQ(2, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply2_SeqNum));
  EXPECT_EQ(now, GetSeqNumToSentRecvTime()->at(kIcmpEchoReply2_SeqNum).first);
  EXPECT_EQ(kIcmpEchoReply3_SeqNum, GetCurrentSequenceNumber());

  // Sending final request.
  testing_clock_.Advance(kSentTime3 - now);
  now = testing_clock_.NowTicks();
  EXPECT_CALL(dispatcher_, PostDelayedTask(_, _, _)).Times(0);
  EXPECT_CALL(*icmp_, Stop()).Times(0);
  TransmitEchoRequestTask(true);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_EQ(3, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply3_SeqNum));
  EXPECT_EQ(now, GetSeqNumToSentRecvTime()->at(kIcmpEchoReply3_SeqNum).first);
  EXPECT_EQ(kIcmpEchoReply3_SeqNum + 1, GetCurrentSequenceNumber());

  // Receive second reply.
  testing_clock_.Advance(kRecvTime2 - now);
  now = testing_clock_.NowTicks();
  uint8_t buffer_2[sizeof(kIpHeader) + sizeof(kIcmpEchoReply2)];
  memcpy(buffer_2, kIpHeader, sizeof(kIpHeader));
  memcpy(buffer_2 + sizeof(kIpHeader), kIcmpEchoReply2,
         sizeof(kIcmpEchoReply2));
  InputData data_2(reinterpret_cast<unsigned char*>(buffer_2),
                   sizeof(buffer_2));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  EXPECT_CALL(*icmp_, Stop()).Times(0);
  OnEchoReplyReceived(&data_2);
  EXPECT_EQ(3, GetSeqNumToSentRecvTime()->size());
  EXPECT_EQ(2, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_TRUE(ReceivedEchoReplySeqNumbersContains(kIcmpEchoReply2_SeqNum));

  // Receive a reply that has an echo ID that does not match that of this
  // ICMP session. This reply will not be processed.
  testing_clock_.Advance(kWrongEchoIDRecvTime - now);
  now = testing_clock_.NowTicks();
  uint8_t buffer_3[sizeof(kIpHeader) + sizeof(kIcmpEchoReplyDifferentEchoID)];
  memcpy(buffer_3, kIpHeader, sizeof(kIpHeader));
  memcpy(buffer_3 + sizeof(kIpHeader), kIcmpEchoReplyDifferentEchoID,
         sizeof(kIcmpEchoReplyDifferentEchoID));
  InputData data_3(reinterpret_cast<unsigned char*>(buffer_3),
                   sizeof(buffer_3));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  EXPECT_CALL(*icmp_, Stop()).Times(0);
  OnEchoReplyReceived(&data_3);
  EXPECT_EQ(3, GetSeqNumToSentRecvTime()->size());
  EXPECT_EQ(2, GetReceivedEchoReplySeqNumbers()->size());

  // Receive third reply, which concludes the ICMP session.
  testing_clock_.Advance(kRecvTime3 - now);
  now = testing_clock_.NowTicks();
  uint8_t buffer_4[sizeof(kIpHeader) + sizeof(kIcmpEchoReply3)];
  memcpy(buffer_4, kIpHeader, sizeof(kIpHeader));
  memcpy(buffer_4 + sizeof(kIpHeader), kIcmpEchoReply3,
         sizeof(kIcmpEchoReply3));
  InputData data_4(reinterpret_cast<unsigned char*>(buffer_4),
                   sizeof(buffer_4));
  EXPECT_CALL(*this, ResultCallback(expected_result));
  EXPECT_CALL(*icmp_, Stop());
  OnEchoReplyReceived(&data_4);
  EXPECT_EQ(3, GetSeqNumToSentRecvTime()->size());
  EXPECT_EQ(3, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_TRUE(ReceivedEchoReplySeqNumbersContains(kIcmpEchoReply3_SeqNum));

  VerifyIcmpSessionStopped();
}

TEST_F(IcmpSessionTest, ICMPv6) {
  // Initiate session.
  IPAddress ipv6_destination(IPAddress::kFamilyIPv6);
  EXPECT_TRUE(ipv6_destination.SetAddressFromString(kIP6Address));
  StartAndVerify(ipv6_destination, kInterfaceIndex);

  // Send an echo request.
  SetCurrentSequenceNumber(kIcmpEchoReply1_SeqNum);
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(true);
  EXPECT_TRUE(GetReceivedEchoReplySeqNumbers()->empty());
  EXPECT_EQ(1, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply1_SeqNum));
  EXPECT_EQ(kIcmpEchoReply2_SeqNum, GetCurrentSequenceNumber());

  // Receive a reply.
  uint8_t buffer_1[sizeof(kIcmpV6EchoReply1)];
  memcpy(buffer_1, kIcmpV6EchoReply1, sizeof(kIcmpV6EchoReply1));
  InputData data_1(reinterpret_cast<unsigned char*>(buffer_1),
                   sizeof(buffer_1));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  OnEchoReplyReceived(&data_1);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_TRUE(ReceivedEchoReplySeqNumbersContains(kIcmpEchoReply1_SeqNum));

  EXPECT_CALL(*icmp_, Stop());
  Stop();
  VerifyIcmpSessionStopped();
}

TEST_F(IcmpSessionTest, SessionTimeoutOrInterrupted) {
  // Test a failed ICMP session where we neither send out all echo requests nor
  // receive all echo replies before stopping the ICMP session (because of a
  // timeout or a manually-triggered stop). Moreover, test that echo requests
  // that are sent unsuccessfully are sent again.

  base::TimeTicks now = testing_clock_.NowTicks();
  base::TimeTicks kSentTime1 = base::TimeTicks::FromInternalValue(10);
  base::TimeTicks kSentTime2 = base::TimeTicks::FromInternalValue(20);
  base::TimeTicks kRecvTime1 = base::TimeTicks::FromInternalValue(30);
  base::TimeTicks kResendTime1 = base::TimeTicks::FromInternalValue(40);

  IcmpSession::IcmpSessionResult expected_partial_result;
  expected_partial_result.push_back(kRecvTime1 - kSentTime1);
  expected_partial_result.push_back(base::TimeDelta());

  // Initiate session.
  IPAddress ipv4_destination(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ipv4_destination.SetAddressFromString(kIPAddress));
  StartAndVerify(ipv4_destination, kInterfaceIndex);

  // Send the first echo request successfully.
  testing_clock_.Advance(kSentTime1 - now);
  now = testing_clock_.NowTicks();
  SetCurrentSequenceNumber(kIcmpEchoReply1_SeqNum);
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(true);
  EXPECT_TRUE(GetReceivedEchoReplySeqNumbers()->empty());
  EXPECT_EQ(1, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply1_SeqNum));
  EXPECT_EQ(now, GetSeqNumToSentRecvTime()->at(kIcmpEchoReply1_SeqNum).first);
  EXPECT_EQ(kIcmpEchoReply2_SeqNum, GetCurrentSequenceNumber());

  // Send the second echo request unsuccessfully.
  testing_clock_.Advance(kSentTime2 - now);
  now = testing_clock_.NowTicks();
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(false);
  EXPECT_TRUE(GetReceivedEchoReplySeqNumbers()->empty());
  EXPECT_EQ(1, GetSeqNumToSentRecvTime()->size());
  EXPECT_FALSE(SeqNumToSentRecvTimeContains(kIcmpEchoReply2_SeqNum));
  // The sequence number should still be incremented when we fail to transmit an
  // echo request.
  EXPECT_EQ(kIcmpEchoReply3_SeqNum, GetCurrentSequenceNumber());

  // Receive first reply.
  testing_clock_.Advance(kRecvTime1 - now);
  now = testing_clock_.NowTicks();
  uint8_t buffer_1[sizeof(kIpHeader) + sizeof(kIcmpEchoReply1)];
  memcpy(buffer_1, kIpHeader, sizeof(kIpHeader));
  memcpy(buffer_1 + sizeof(kIpHeader), kIcmpEchoReply1,
         sizeof(kIcmpEchoReply1));
  InputData data_1(reinterpret_cast<unsigned char*>(buffer_1),
                   sizeof(buffer_1));
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  OnEchoReplyReceived(&data_1);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_TRUE(ReceivedEchoReplySeqNumbersContains(kIcmpEchoReply1_SeqNum));

  // Resend second echo request successfully.
  testing_clock_.Advance(kResendTime1 - now);
  now = testing_clock_.NowTicks();
  EXPECT_CALL(dispatcher_,
              PostDelayedTask(_, _, GetEchoRequestIntervalSeconds() * 1000));
  TransmitEchoRequestTask(true);
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  EXPECT_EQ(2, GetSeqNumToSentRecvTime()->size());
  EXPECT_TRUE(SeqNumToSentRecvTimeContains(kIcmpEchoReply3_SeqNum));
  EXPECT_EQ(now, GetSeqNumToSentRecvTime()->at(kIcmpEchoReply3_SeqNum).first);
  EXPECT_EQ(kIcmpEchoReply3_SeqNum + 1, GetCurrentSequenceNumber());

  // Timeout triggered, so report partial results.
  EXPECT_CALL(*this, ResultCallback(expected_partial_result));
  EXPECT_CALL(*icmp_, Stop());
  ReportResultAndStopSession();
  EXPECT_EQ(2, GetSeqNumToSentRecvTime()->size());
  EXPECT_EQ(1, GetReceivedEchoReplySeqNumbers()->size());
  VerifyIcmpSessionStopped();
}

TEST_F(IcmpSessionTest, DoNotReportResultsOnStop) {
  // Initiate session.
  IPAddress ipv4_destination(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ipv4_destination.SetAddressFromString(kIPAddress));
  StartAndVerify(ipv4_destination, kInterfaceIndex);

  // Session interrupted manually by calling Stop(), so do not report results.
  EXPECT_CALL(*this, ResultCallback(_)).Times(0);
  EXPECT_CALL(*icmp_, Stop());
  Stop();
  VerifyIcmpSessionStopped();
}

TEST_F(IcmpSessionTest, AnyRepliesReceived) {
  IcmpSession::IcmpSessionResult none_sent;
  EXPECT_FALSE(IcmpSession::AnyRepliesReceived(none_sent));

  IcmpSession::IcmpSessionResult two_sent_none_received;
  two_sent_none_received.push_back(base::TimeDelta());
  two_sent_none_received.push_back(base::TimeDelta());
  EXPECT_FALSE(IcmpSession::AnyRepliesReceived(two_sent_none_received));

  IcmpSession::IcmpSessionResult one_sent_one_received;
  one_sent_one_received.push_back(base::TimeDelta::FromSeconds(10));
  EXPECT_TRUE(IcmpSession::AnyRepliesReceived(one_sent_one_received));

  IcmpSession::IcmpSessionResult two_sent_one_received;
  two_sent_one_received.push_back(base::TimeDelta::FromSeconds(20));
  two_sent_one_received.push_back(base::TimeDelta());
  EXPECT_TRUE(IcmpSession::AnyRepliesReceived(two_sent_one_received));
}

TEST_F(IcmpSessionTest, IsPacketLossPercentageGreaterThan) {
  // If we sent no echo requests out, we expect no replies, therefore we have
  // 0% packet loss.
  IcmpSession::IcmpSessionResult none_sent_none_received;
  EXPECT_FALSE(IcmpSession::IsPacketLossPercentageGreaterThan(
      none_sent_none_received, 0));

  // If we receive all replies, we experience 0% packet loss.
  IcmpSession::IcmpSessionResult three_sent_three_received;
  three_sent_three_received.push_back(base::TimeDelta::FromSeconds(10));
  three_sent_three_received.push_back(base::TimeDelta::FromSeconds(10));
  three_sent_three_received.push_back(base::TimeDelta::FromSeconds(10));
  EXPECT_FALSE(IcmpSession::IsPacketLossPercentageGreaterThan(
      three_sent_three_received, 0));

  // If we sent 3 requests and received 2 replies, we have ~33% packet loss.
  IcmpSession::IcmpSessionResult three_sent_two_received;
  three_sent_two_received.push_back(base::TimeDelta::FromSeconds(10));
  three_sent_two_received.push_back(base::TimeDelta::FromSeconds(10));
  three_sent_two_received.push_back(base::TimeDelta());
  EXPECT_FALSE(IcmpSession::IsPacketLossPercentageGreaterThan(
      three_sent_two_received, 60));
  EXPECT_FALSE(IcmpSession::IsPacketLossPercentageGreaterThan(
      three_sent_two_received, 33));
  EXPECT_TRUE(IcmpSession::IsPacketLossPercentageGreaterThan(
      three_sent_two_received, 32));
  EXPECT_TRUE(IcmpSession::IsPacketLossPercentageGreaterThan(
      three_sent_two_received, 10));
}

}  // namespace shill
