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

// This file provides tests for individual messages.  It tests
// NetlinkMessageFactory's ability to create specific message types and it
// tests the various NetlinkMessage types' ability to parse those
// messages.

// This file tests the public interface to NetlinkManager.
#include "shill/net/netlink_manager.h"

#include <errno.h>

#include <map>
#include <string>
#include <vector>

#include <base/logging.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "shill/net/io_handler.h"
#include "shill/net/mock_io_handler_factory.h"
#include "shill/net/mock_netlink_socket.h"
#include "shill/net/mock_sockets.h"
#include "shill/net/mock_time.h"
#include "shill/net/netlink_attribute.h"
#include "shill/net/netlink_packet.h"
#include "shill/net/nl80211_message.h"

using testing::_;
using testing::Invoke;
using testing::Mock;
using testing::Return;
using testing::SetArgPointee;
using testing::StrictMock;
using testing::Test;

namespace shill {

namespace {

// These data blocks have been collected by shill using NetlinkManager while,
// simultaneously (and manually) comparing shill output with that of the 'iw'
// code from which it was derived.  The test strings represent the raw packet
// data coming from the kernel.  The comments above each of these strings is
// the markup that "iw" outputs for ech of these packets.

// These constants are consistent throughout the packets, below.

const uint16_t kNl80211FamilyId = 0x13;

// Family and group Ids.
const char kFamilyStoogesString[] = "stooges";  // Not saved as a legal family.
const char kGroupMoeString[] = "moe";           // Not saved as a legal group.
const char kFamilyMarxString[] = "marx";
const uint16_t kFamilyMarxNumber = 20;
const char kGroupGrouchoString[] = "groucho";
const uint32_t kGroupGrouchoNumber = 21;
const char kGroupHarpoString[] = "harpo";
const uint32_t kGroupHarpoNumber = 22;
const char kGroupChicoString[] = "chico";
const uint32_t kGroupChicoNumber = 23;
const char kGroupZeppoString[] = "zeppo";
const uint32_t kGroupZeppoNumber = 24;
const char kGroupGummoString[] = "gummo";
const uint32_t kGroupGummoNumber = 25;

// wlan0 (phy #0): disconnected (by AP) reason: 2: Previous authentication no
// longer valid

const unsigned char kNL80211_CMD_DISCONNECT[] = {
    0x30, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00,
    0x06, 0x00, 0x36, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x47, 0x00};

const unsigned char kNLMSG_ACK[] = {0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
                                    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

// Error code 1.
const unsigned char kNLMSG_Error[] = {0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,
                                      0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
                                      0x00, 0x00, 0x00, 0x00, 0x00, 0x01};

const char kGetFamilyCommandString[] = "CTRL_CMD_GETFAMILY";

}  // namespace

class NetlinkManagerTest : public Test {
 public:
  NetlinkManagerTest()
      : netlink_manager_(NetlinkManager::GetInstance()),
        netlink_socket_(new MockNetlinkSocket()),
        sockets_(new MockSockets),
        saved_sequence_number_(0) {
    EXPECT_NE(nullptr, netlink_manager_);
    netlink_manager_->message_types_[Nl80211Message::kMessageTypeString]
        .family_id = kNl80211FamilyId;
    netlink_manager_->message_types_[kFamilyMarxString].family_id =
        kFamilyMarxNumber;
    netlink_manager_->message_types_[kFamilyMarxString].groups =
        std::map<std::string, uint32_t>{
            {kGroupGrouchoString, kGroupGrouchoNumber},
            {kGroupHarpoString, kGroupHarpoNumber},
            {kGroupChicoString, kGroupChicoNumber},
            {kGroupZeppoString, kGroupZeppoNumber},
            {kGroupGummoString, kGroupGummoNumber}};
    netlink_manager_->message_factory_.AddFactoryMethod(
        kNl80211FamilyId, base::Bind(&Nl80211Message::CreateMessage));
    Nl80211Message::SetMessageType(kNl80211FamilyId);
    netlink_socket_->sockets_.reset(sockets_);       // Passes ownership.
    netlink_manager_->sock_.reset(netlink_socket_);  // Passes ownership.
    netlink_manager_->io_handler_factory_ = &io_handler_factory_;
    EXPECT_TRUE(netlink_manager_->Init());
  }

  ~NetlinkManagerTest() {
    // NetlinkManager is a singleton, so reset its state for the next test.
    netlink_manager_->Reset(true);
  }

  // |SaveReply|, |SendMessage|, and |ReplyToSentMessage| work together to
  // enable a test to get a response to a sent message.  They must be called
  // in the order, above, so that a) a reply message is available to b) have
  // its sequence number replaced, and then c) sent back to the code.
  void SaveReply(const ByteString& message) { saved_message_ = message; }

  // Replaces the |saved_message_|'s sequence number with the sent value.
  bool SendMessage(const ByteString& outgoing_message) {
    if (outgoing_message.GetLength() < sizeof(nlmsghdr)) {
      LOG(ERROR) << "Outgoing message is too short";
      return false;
    }
    const nlmsghdr* outgoing_header =
        reinterpret_cast<const nlmsghdr*>(outgoing_message.GetConstData());

    if (saved_message_.GetLength() < sizeof(nlmsghdr)) {
      LOG(ERROR) << "Saved message is too short; have you called |SaveReply|?";
      return false;
    }
    nlmsghdr* reply_header =
        reinterpret_cast<nlmsghdr*>(saved_message_.GetData());

    reply_header->nlmsg_seq = outgoing_header->nlmsg_seq;
    saved_sequence_number_ = reply_header->nlmsg_seq;
    return true;
  }

  bool ReplyToSentMessage(ByteString* message) {
    if (!message) {
      return false;
    }
    *message = saved_message_;
    return true;
  }

  bool ReplyWithRandomMessage(ByteString* message) {
    GetFamilyMessage get_family_message;
    // Any number that's not 0 or 1 is acceptable, here.  Zero is bad because
    // we want to make sure that this message is different than the main
    // send/receive pair.  One is bad because the default for
    // |saved_sequence_number_| is zero and the likely default value for the
    // first sequence number generated from the code is 1.
    const uint32_t kRandomOffset = 1003;
    if (!message) {
      return false;
    }
    *message =
        get_family_message.Encode(saved_sequence_number_ + kRandomOffset);
    return true;
  }

 protected:
  class MockHandlerNetlink {
   public:
    MockHandlerNetlink()
        : on_netlink_message_(base::Bind(&MockHandlerNetlink::OnNetlinkMessage,
                                         base::Unretained(this))) {}
    MockHandlerNetlink(const MockHandlerNetlink&) = delete;
    MockHandlerNetlink& operator=(const MockHandlerNetlink&) = delete;

    MOCK_METHOD(void, OnNetlinkMessage, (const NetlinkMessage& msg));
    const NetlinkManager::NetlinkMessageHandler& on_netlink_message() const {
      return on_netlink_message_;
    }

   private:
    NetlinkManager::NetlinkMessageHandler on_netlink_message_;
  };

  class MockHandlerNetlinkAuxilliary {
   public:
    MockHandlerNetlinkAuxilliary()
        : on_netlink_message_(
              base::Bind(&MockHandlerNetlinkAuxilliary::OnErrorHandler,
                         base::Unretained(this))) {}
    MockHandlerNetlinkAuxilliary(const MockHandlerNetlinkAuxilliary&) = delete;
    MockHandlerNetlinkAuxilliary& operator=(
        const MockHandlerNetlinkAuxilliary&) = delete;

    MOCK_METHOD(void,
                OnErrorHandler,
                (NetlinkManager::AuxilliaryMessageType, const NetlinkMessage*));
    const NetlinkManager::NetlinkAuxilliaryMessageHandler& on_netlink_message()
        const {
      return on_netlink_message_;
    }

   private:
    NetlinkManager::NetlinkAuxilliaryMessageHandler on_netlink_message_;
  };

  class MockHandler80211 {
   public:
    MockHandler80211()
        : on_netlink_message_(base::Bind(&MockHandler80211::OnNetlinkMessage,
                                         base::Unretained(this))) {}
    MockHandler80211(const MockHandler80211&) = delete;
    MockHandler80211& operator=(const MockHandler80211&) = delete;

    MOCK_METHOD(void, OnNetlinkMessage, (const Nl80211Message&));
    const NetlinkManager::Nl80211MessageHandler& on_netlink_message() const {
      return on_netlink_message_;
    }

   private:
    NetlinkManager::Nl80211MessageHandler on_netlink_message_;
  };

  class MockHandlerNetlinkAck {
   public:
    MockHandlerNetlinkAck()
        : on_netlink_message_(base::Bind(&MockHandlerNetlinkAck::OnAckHandler,
                                         base::Unretained(this))) {}
    MockHandlerNetlinkAck(const MockHandlerNetlinkAck&) = delete;
    MockHandlerNetlinkAck& operator=(const MockHandlerNetlinkAck&) = delete;

    MOCK_METHOD(void, OnAckHandler, (bool*));
    const NetlinkManager::NetlinkAckHandler& on_netlink_message() const {
      return on_netlink_message_;
    }

   private:
    NetlinkManager::NetlinkAckHandler on_netlink_message_;
  };

  void Reset() { netlink_manager_->Reset(false); }

  NetlinkManager* netlink_manager_;
  MockNetlinkSocket* netlink_socket_;  // Owned by |netlink_manager_|.
  MockSockets* sockets_;               // Owned by |netlink_socket_|.
  StrictMock<MockIOHandlerFactory> io_handler_factory_;
  ByteString saved_message_;
  uint32_t saved_sequence_number_;
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
};

namespace {

class TimeFunctor {
 public:
  TimeFunctor(time_t tv_sec, suseconds_t tv_usec) {
    return_value_.tv_sec = tv_sec;
    return_value_.tv_usec = tv_usec;
  }

  TimeFunctor() {
    return_value_.tv_sec = 0;
    return_value_.tv_usec = 0;
  }

  TimeFunctor(const TimeFunctor& other) {
    return_value_.tv_sec = other.return_value_.tv_sec;
    return_value_.tv_usec = other.return_value_.tv_usec;
  }

  TimeFunctor& operator=(const TimeFunctor& rhs) {
    return_value_.tv_sec = rhs.return_value_.tv_sec;
    return_value_.tv_usec = rhs.return_value_.tv_usec;
    return *this;
  }

  // Replaces GetTimeMonotonic.
  int operator()(struct timeval* answer) {
    if (answer) {
      *answer = return_value_;
    }
    return 0;
  }

 private:
  struct timeval return_value_;

  // No DISALLOW_COPY_AND_ASSIGN since testing::Invoke uses copy.
};

}  // namespace

TEST_F(NetlinkManagerTest, Start) {
  EXPECT_CALL(io_handler_factory_, CreateIOInputHandler(_, _, _));
  netlink_manager_->Start();
}

TEST_F(NetlinkManagerTest, SubscribeToEvents) {
  // Family not registered.
  EXPECT_CALL(*netlink_socket_, SubscribeToEvents(_)).Times(0);
  EXPECT_FALSE(netlink_manager_->SubscribeToEvents(kFamilyStoogesString,
                                                   kGroupMoeString));

  // Group not part of family
  EXPECT_CALL(*netlink_socket_, SubscribeToEvents(_)).Times(0);
  EXPECT_FALSE(
      netlink_manager_->SubscribeToEvents(kFamilyMarxString, kGroupMoeString));

  // Family registered and group part of family.
  EXPECT_CALL(*netlink_socket_, SubscribeToEvents(kGroupHarpoNumber))
      .WillOnce(Return(true));
  EXPECT_TRUE(netlink_manager_->SubscribeToEvents(kFamilyMarxString,
                                                  kGroupHarpoString));
}

TEST_F(NetlinkManagerTest, GetFamily) {
  const uint16_t kSampleMessageType = 42;
  const std::string kSampleMessageName = "SampleMessageName";
  const uint32_t kRandomSequenceNumber = 3;

  NewFamilyMessage new_family_message;
  new_family_message.attributes()->CreateControlAttribute(CTRL_ATTR_FAMILY_ID);
  new_family_message.attributes()->SetU16AttributeValue(CTRL_ATTR_FAMILY_ID,
                                                        kSampleMessageType);
  new_family_message.attributes()->CreateControlAttribute(
      CTRL_ATTR_FAMILY_NAME);
  new_family_message.attributes()->SetStringAttributeValue(
      CTRL_ATTR_FAMILY_NAME, kSampleMessageName);

  // The sequence number is immaterial since it'll be overwritten.
  SaveReply(new_family_message.Encode(kRandomSequenceNumber));
  EXPECT_CALL(*netlink_socket_, SendMessage(_))
      .WillOnce(Invoke(this, &NetlinkManagerTest::SendMessage));
  EXPECT_CALL(*netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
  EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillOnce(Return(1));
  EXPECT_CALL(*netlink_socket_, RecvMessage(_))
      .WillOnce(Invoke(this, &NetlinkManagerTest::ReplyToSentMessage));
  NetlinkMessageFactory::FactoryMethod null_factory;
  EXPECT_EQ(kSampleMessageType,
            netlink_manager_->GetFamily(kSampleMessageName, null_factory));
}

TEST_F(NetlinkManagerTest, GetFamilyOneInterstitialMessage) {
  Reset();

  const uint16_t kSampleMessageType = 42;
  const std::string kSampleMessageName = "SampleMessageName";
  const uint32_t kRandomSequenceNumber = 3;

  NewFamilyMessage new_family_message;
  new_family_message.attributes()->CreateControlAttribute(CTRL_ATTR_FAMILY_ID);
  new_family_message.attributes()->SetU16AttributeValue(CTRL_ATTR_FAMILY_ID,
                                                        kSampleMessageType);
  new_family_message.attributes()->CreateControlAttribute(
      CTRL_ATTR_FAMILY_NAME);
  new_family_message.attributes()->SetStringAttributeValue(
      CTRL_ATTR_FAMILY_NAME, kSampleMessageName);

  // The sequence number is immaterial since it'll be overwritten.
  SaveReply(new_family_message.Encode(kRandomSequenceNumber));
  EXPECT_CALL(*netlink_socket_, SendMessage(_))
      .WillOnce(Invoke(this, &NetlinkManagerTest::SendMessage));
  EXPECT_CALL(*netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
  EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillRepeatedly(Return(1));
  EXPECT_CALL(*netlink_socket_, RecvMessage(_))
      .WillOnce(Invoke(this, &NetlinkManagerTest::ReplyWithRandomMessage))
      .WillOnce(Invoke(this, &NetlinkManagerTest::ReplyToSentMessage));
  NetlinkMessageFactory::FactoryMethod null_factory;
  EXPECT_EQ(kSampleMessageType,
            netlink_manager_->GetFamily(kSampleMessageName, null_factory));
}

TEST_F(NetlinkManagerTest, GetFamilyTimeout) {
  Reset();
  MockTime time;
  Time* old_time = netlink_manager_->time_;
  netlink_manager_->time_ = &time;

  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  time_t kStartSeconds = 1234;  // Arbitrary.
  suseconds_t kSmallUsec = 100;
  EXPECT_CALL(time, GetTimeMonotonic(_))
      .WillOnce(Invoke(TimeFunctor(kStartSeconds, 0)))
      .  // Initial time.
      WillOnce(Invoke(TimeFunctor(kStartSeconds, kSmallUsec)))
      .WillOnce(Invoke(TimeFunctor(kStartSeconds, 2 * kSmallUsec)))
      .WillOnce(Invoke(TimeFunctor(
          kStartSeconds + NetlinkManager::kMaximumNewFamilyWaitSeconds + 1,
          NetlinkManager::kMaximumNewFamilyWaitMicroSeconds)));
  EXPECT_CALL(*netlink_socket_, file_descriptor()).WillRepeatedly(Return(0));
  EXPECT_CALL(*sockets_, Select(_, _, _, _, _)).WillRepeatedly(Return(1));
  EXPECT_CALL(*netlink_socket_, RecvMessage(_))
      .WillRepeatedly(
          Invoke(this, &NetlinkManagerTest::ReplyWithRandomMessage));
  NetlinkMessageFactory::FactoryMethod null_factory;

  const std::string kSampleMessageName = "SampleMessageName";
  EXPECT_EQ(NetlinkMessage::kIllegalMessageType,
            netlink_manager_->GetFamily(kSampleMessageName, null_factory));
  netlink_manager_->time_ = old_time;
}

TEST_F(NetlinkManagerTest, BroadcastHandler) {
  Reset();
  MutableNetlinkPacket packet(kNL80211_CMD_DISCONNECT,
                              sizeof(kNL80211_CMD_DISCONNECT));

  MockHandlerNetlink handler1;
  MockHandlerNetlink handler2;

  // Simple, 1 handler, case.
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
  EXPECT_FALSE(
      netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
  netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
  EXPECT_TRUE(
      netlink_manager_->FindBroadcastHandler(handler1.on_netlink_message()));
  netlink_manager_->OnNlMessageReceived(&packet);
  packet.ResetConsumedBytes();

  // Add a second handler.
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
  EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->AddBroadcastHandler(handler2.on_netlink_message());
  netlink_manager_->OnNlMessageReceived(&packet);
  packet.ResetConsumedBytes();

  // Verify that a handler can't be added twice.
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
  EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
  netlink_manager_->OnNlMessageReceived(&packet);
  packet.ResetConsumedBytes();

  // Check that we can remove a handler.
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
  EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
  EXPECT_TRUE(
      netlink_manager_->RemoveBroadcastHandler(handler1.on_netlink_message()));
  netlink_manager_->OnNlMessageReceived(&packet);
  packet.ResetConsumedBytes();

  // Check that re-adding the handler goes smoothly.
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(1);
  EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->AddBroadcastHandler(handler1.on_netlink_message());
  netlink_manager_->OnNlMessageReceived(&packet);
  packet.ResetConsumedBytes();

  // Check that ClearBroadcastHandlers works.
  netlink_manager_->ClearBroadcastHandlers();
  EXPECT_CALL(handler1, OnNetlinkMessage(_)).Times(0);
  EXPECT_CALL(handler2, OnNetlinkMessage(_)).Times(0);
  netlink_manager_->OnNlMessageReceived(&packet);
}

TEST_F(NetlinkManagerTest, MessageHandler) {
  Reset();
  MockHandlerNetlink handler_broadcast;
  EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
      handler_broadcast.on_netlink_message()));

  Nl80211Message sent_message_1(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
  MockHandler80211 handler_sent_1;

  Nl80211Message sent_message_2(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
  MockHandler80211 handler_sent_2;

  // Set up the received message as a response to sent_message_1.
  MutableNetlinkPacket received_message(kNL80211_CMD_DISCONNECT,
                                        sizeof(kNL80211_CMD_DISCONNECT));

  // Verify that generic handler gets called for a message when no
  // message-specific handler has been installed.
  EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
  received_message.ResetConsumedBytes();

  // Send the message and give our handler.  Verify that we get called back.
  NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
  NetlinkManager::NetlinkAckHandler null_ack_handler;
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message_1, handler_sent_1.on_netlink_message(), null_ack_handler,
      null_error_handler));
  // Make it appear that this message is in response to our sent message.
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
  received_message.ResetConsumedBytes();

  // Verify that broadcast handler is called for the message after the
  // message-specific handler is called once.
  EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
  received_message.ResetConsumedBytes();

  // Install and then uninstall message-specific handler; verify broadcast
  // handler is called on message receipt.
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message_1, handler_sent_1.on_netlink_message(), null_ack_handler,
      null_error_handler));
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());
  EXPECT_TRUE(netlink_manager_->RemoveMessageHandler(sent_message_1));
  EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
  received_message.ResetConsumedBytes();

  // Install handler for different message; verify that broadcast handler is
  // called for _this_ message.
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message_2, handler_sent_2.on_netlink_message(), null_ack_handler,
      null_error_handler));
  EXPECT_CALL(handler_broadcast, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
  received_message.ResetConsumedBytes();

  // Change the ID for the message to that of the second handler; verify that
  // the appropriate handler is called for _that_ message.
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_2, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_message);
}

TEST_F(NetlinkManagerTest, AckHandler) {
  Reset();

  Nl80211Message sent_message(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
  MockHandler80211 handler_sent_1;
  MockHandlerNetlinkAck handler_sent_2;

  // Send the message and give a Nl80211 response handlerand an Ack
  // handler that does not remove other callbacks after execution.
  // Receive an Ack message and verify that the Ack handler is invoked.
  NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message, handler_sent_1.on_netlink_message(),
      handler_sent_2.on_netlink_message(), null_error_handler));
  // Set up message as an ack in response to sent_message.
  MutableNetlinkPacket received_ack_message(kNLMSG_ACK, sizeof(kNLMSG_ACK));

  // Make it appear that this message is in response to our sent message.
  received_ack_message.SetMessageSequence(
      netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_2, OnAckHandler(_))
      .Times(1)
      .WillOnce(SetArgPointee<0>(false));  // Do not remove callbacks
  netlink_manager_->OnNlMessageReceived(&received_ack_message);

  // Receive an Nl80211 response message after handling the Ack and verify
  // that the Nl80211 response handler is invoked to ensure that it was not
  // deleted after the Ack handler was executed.
  MutableNetlinkPacket received_response_message(
      kNL80211_CMD_DISCONNECT, sizeof(kNL80211_CMD_DISCONNECT));

  // Make it appear that this message is in response to our sent message.
  received_response_message.SetMessageSequence(
      netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_response_message);
  received_response_message.ResetConsumedBytes();

  // Send the message and give a Nl80211 response handler and Ack handler again,
  // but remove other callbacks after executing the Ack handler.
  // Receive an Ack message and verify the Ack handler is invoked.
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message, handler_sent_1.on_netlink_message(),
      handler_sent_2.on_netlink_message(), null_error_handler));
  received_ack_message.ResetConsumedBytes();
  received_ack_message.SetMessageSequence(
      netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_2, OnAckHandler(_))
      .Times(1)
      .WillOnce(SetArgPointee<0>(true));  // Remove callbacks
  netlink_manager_->OnNlMessageReceived(&received_ack_message);

  // Receive an Nl80211 response message after handling the Ack and verify
  // that the Nl80211 response handler is not invoked this time, since it should
  // have been deleted after calling the Ack handler.
  received_response_message.SetMessageSequence(
      received_ack_message.GetNlMsgHeader().nlmsg_seq);
  EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(0);
  netlink_manager_->OnNlMessageReceived(&received_response_message);
}

TEST_F(NetlinkManagerTest, ErrorHandler) {
  Nl80211Message sent_message(CTRL_CMD_GETFAMILY, kGetFamilyCommandString);
  MockHandler80211 handler_sent_1;
  MockHandlerNetlinkAck handler_sent_2;
  MockHandlerNetlinkAuxilliary handler_sent_3;

  // Send the message and receive a netlink reply.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message, handler_sent_1.on_netlink_message(),
      handler_sent_2.on_netlink_message(),
      handler_sent_3.on_netlink_message()));
  MutableNetlinkPacket received_response_message(
      kNL80211_CMD_DISCONNECT, sizeof(kNL80211_CMD_DISCONNECT));
  received_response_message.SetMessageSequence(
      netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_1, OnNetlinkMessage(_)).Times(1);
  netlink_manager_->OnNlMessageReceived(&received_response_message);

  // Send the message again, but receive an error response.
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &sent_message, handler_sent_1.on_netlink_message(),
      handler_sent_2.on_netlink_message(),
      handler_sent_3.on_netlink_message()));
  MutableNetlinkPacket received_error_message(kNLMSG_Error,
                                              sizeof(kNLMSG_Error));
  received_error_message.SetMessageSequence(
      netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(handler_sent_3,
              OnErrorHandler(NetlinkManager::kErrorFromKernel, _))
      .Times(1);
  netlink_manager_->OnNlMessageReceived(&received_error_message);

  // Put the state of the singleton back where it was.
  Reset();
}

TEST_F(NetlinkManagerTest, MultipartMessageHandler) {
  Reset();

  // Install a broadcast handler.
  MockHandlerNetlink broadcast_handler;
  EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
      broadcast_handler.on_netlink_message()));

  // Build a message and send it in order to install a response handler.
  TriggerScanMessage trigger_scan_message;
  MockHandler80211 response_handler;
  MockHandlerNetlinkAuxilliary auxilliary_handler;
  MockHandlerNetlinkAck ack_handler;
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &trigger_scan_message, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));

  // Build a multi-part response (well, it's just one message but it'll be
  // received multiple times).
  const uint32_t kSequenceNumber = 32;  // Arbitrary (replaced, later).
  NewScanResultsMessage new_scan_results;
  new_scan_results.AddFlag(NLM_F_MULTI);
  ByteString new_scan_results_bytes(new_scan_results.Encode(kSequenceNumber));
  MutableNetlinkPacket received_message(new_scan_results_bytes.GetData(),
                                        new_scan_results_bytes.GetLength());
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());

  // Verify that the message-specific handler is called.
  EXPECT_CALL(response_handler, OnNetlinkMessage(_));
  netlink_manager_->OnNlMessageReceived(&received_message);

  // Verify that the message-specific handler is still called.
  EXPECT_CALL(response_handler, OnNetlinkMessage(_));
  received_message.ResetConsumedBytes();
  netlink_manager_->OnNlMessageReceived(&received_message);

  // Build a Done message with the sent-message sequence number.
  DoneMessage done_message;
  done_message.AddFlag(NLM_F_MULTI);
  ByteString done_message_bytes(
      done_message.Encode(netlink_socket_->GetLastSequenceNumber()));
  NetlinkPacket done_packet(done_message_bytes.GetData(),
                            done_message_bytes.GetLength());

  // Verify that the message-specific auxilliary handler is called for the done
  // message, with the correct message type.
  EXPECT_CALL(auxilliary_handler, OnErrorHandler(NetlinkManager::kDone, _));

  netlink_manager_->OnNlMessageReceived(&done_packet);

  // Verify that broadcast handler is called now that the done message has
  // been seen.
  EXPECT_CALL(response_handler, OnNetlinkMessage(_)).Times(0);
  EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _)).Times(0);
  EXPECT_CALL(ack_handler, OnAckHandler(_)).Times(0);
  EXPECT_CALL(broadcast_handler, OnNetlinkMessage(_)).Times(1);
  received_message.ResetConsumedBytes();
  netlink_manager_->OnNlMessageReceived(&received_message);
}

TEST_F(NetlinkManagerTest, TimeoutResponseHandlers) {
  Reset();
  MockHandlerNetlink broadcast_handler;
  EXPECT_TRUE(netlink_manager_->AddBroadcastHandler(
      broadcast_handler.on_netlink_message()));

  // Set up the received message as a response to the get_wiphy_message
  // we're going to send.
  NewWiphyMessage new_wiphy_message;
  const uint32_t kRandomSequenceNumber = 3;
  ByteString new_wiphy_message_bytes =
      new_wiphy_message.Encode(kRandomSequenceNumber);
  MutableNetlinkPacket received_message(new_wiphy_message_bytes.GetData(),
                                        new_wiphy_message_bytes.GetLength());

  // Setup a random received message to trigger wiping out old messages.
  NewScanResultsMessage new_scan_results;
  ByteString new_scan_results_bytes =
      new_scan_results.Encode(kRandomSequenceNumber);

  // Setup the timestamps of various messages
  MockTime time;
  Time* old_time = netlink_manager_->time_;
  netlink_manager_->time_ = &time;

  time_t kStartSeconds = 1234;  // Arbitrary.
  suseconds_t kSmallUsec = 100;
  EXPECT_CALL(time, GetTimeMonotonic(_))
      .WillOnce(Invoke(TimeFunctor(kStartSeconds, 0)))
      .  // Initial time.
      WillOnce(Invoke(TimeFunctor(kStartSeconds, kSmallUsec)))
      .

      WillOnce(Invoke(TimeFunctor(kStartSeconds, 0)))
      .  // Initial time.
      WillOnce(Invoke(TimeFunctor(
          kStartSeconds + NetlinkManager::kResponseTimeoutSeconds + 1,
          NetlinkManager::kResponseTimeoutMicroSeconds)));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillRepeatedly(Return(true));

  GetWiphyMessage get_wiphy_message;
  MockHandler80211 response_handler;
  MockHandlerNetlinkAuxilliary auxilliary_handler;
  MockHandlerNetlinkAck ack_handler;

  GetRegMessage get_reg_message;  // Just a message to trigger timeout.
  NetlinkManager::Nl80211MessageHandler null_message_handler;
  NetlinkManager::NetlinkAuxilliaryMessageHandler null_error_handler;
  NetlinkManager::NetlinkAckHandler null_ack_handler;

  // Send two messages within the message handler timeout; verify that we
  // get called back (i.e., that the first handler isn't discarded).
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_wiphy_message, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_reg_message, null_message_handler, null_ack_handler,
      null_error_handler));
  EXPECT_CALL(response_handler, OnNetlinkMessage(_));
  netlink_manager_->OnNlMessageReceived(&received_message);

  // Send two messages at an interval greater than the message handler timeout
  // before the response to the first arrives.  Verify that the error handler
  // for the first message is called (with a timeout flag) and that the
  // broadcast handler gets called, instead of the message's handler.
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_wiphy_message, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  received_message.ResetConsumedBytes();
  received_message.SetMessageSequence(netlink_socket_->GetLastSequenceNumber());
  EXPECT_CALL(
      auxilliary_handler,
      OnErrorHandler(NetlinkManager::kTimeoutWaitingForResponse, nullptr));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_reg_message, null_message_handler, null_ack_handler,
      null_error_handler));
  EXPECT_CALL(response_handler, OnNetlinkMessage(_)).Times(0);
  EXPECT_CALL(broadcast_handler, OnNetlinkMessage(_));
  netlink_manager_->OnNlMessageReceived(&received_message);

  // Put the state of the singleton back where it was.
  netlink_manager_->time_ = old_time;
}

TEST_F(NetlinkManagerTest, PendingDump) {
  // Set up the responses to the two get station messages  we're going to send.
  // The response to then first message is a 2-message multi-part response,
  // while the response to the second is a single response.
  NewStationMessage new_station_message_1_pt1;
  NewStationMessage new_station_message_1_pt2;
  NewStationMessage new_station_message_2;
  const uint32_t kRandomSequenceNumber = 3;
  new_station_message_1_pt1.AddFlag(NLM_F_MULTI);
  new_station_message_1_pt2.AddFlag(NLM_F_MULTI);
  ByteString new_station_message_1_pt1_bytes =
      new_station_message_1_pt1.Encode(kRandomSequenceNumber);
  ByteString new_station_message_1_pt2_bytes =
      new_station_message_1_pt2.Encode(kRandomSequenceNumber);
  ByteString new_station_message_2_bytes =
      new_station_message_2.Encode(kRandomSequenceNumber);
  MutableNetlinkPacket received_message_1_pt1(
      new_station_message_1_pt1_bytes.GetData(),
      new_station_message_1_pt1_bytes.GetLength());
  MutableNetlinkPacket received_message_1_pt2(
      new_station_message_1_pt2_bytes.GetData(),
      new_station_message_1_pt2_bytes.GetLength());
  received_message_1_pt2.SetMessageType(NLMSG_DONE);
  MutableNetlinkPacket received_message_2(
      new_station_message_2_bytes.GetData(),
      new_station_message_2_bytes.GetLength());

  // The two get station messages (with the dump flag set) will be sent one
  // after another. The second message can only be sent once all replies to the
  // first have been received. The get wiphy message will be sent while waiting
  // for replies from the first get station message.
  GetStationMessage get_station_message_1;
  get_station_message_1.AddFlag(NLM_F_DUMP);
  GetStationMessage get_station_message_2;
  get_station_message_2.AddFlag(NLM_F_DUMP);
  GetWiphyMessage get_wiphy_message;
  MockHandler80211 response_handler;
  MockHandlerNetlinkAuxilliary auxilliary_handler;
  MockHandlerNetlinkAck ack_handler;

  // Send the first get station message, which should be sent immediately and
  // trigger a pending dump.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_1, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_1_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Send the second get station message before the replies to the first
  // get station message have been received. This should cause the message
  // to be enqueued for later sending.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).Times(0);
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_2, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_2_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Send the get wiphy message before the replies to the first
  // get station message have been received. Since this message does not have
  // the NLM_F_DUMP flag set, it will not be enqueued and sent immediately.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_wiphy_message, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Now we receive the two-part response to the first message.
  // On receiving the first part, keep waiting for second part.
  received_message_1_pt1.SetMessageSequence(get_station_message_1_seq_num);
  EXPECT_CALL(response_handler, OnNetlinkMessage(_));
  netlink_manager_->OnNlMessageReceived(&received_message_1_pt1);
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // On receiving second part of the message, report done to the error handler,
  // and dispatch the next message in the queue.
  received_message_1_pt2.SetMessageSequence(get_station_message_1_seq_num);
  EXPECT_CALL(auxilliary_handler, OnErrorHandler(NetlinkManager::kDone, _));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  netlink_manager_->OnNlMessageReceived(&received_message_1_pt2);
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_2_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Receive response to second dump message, and stop waiting for dump replies.
  received_message_2.SetMessageSequence(get_station_message_2_seq_num);
  EXPECT_CALL(response_handler, OnNetlinkMessage(_));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).Times(0);
  netlink_manager_->OnNlMessageReceived(&received_message_2);
  EXPECT_FALSE(netlink_manager_->IsDumpPending());
  EXPECT_TRUE(netlink_manager_->pending_messages_.empty());
  EXPECT_EQ(0, netlink_manager_->PendingDumpSequenceNumber());

  // Put the state of the singleton back where it was.
  Reset();
}

TEST_F(NetlinkManagerTest, PendingDump_Timeout) {
  // These two messages will be sent one after another.
  GetStationMessage get_station_message_1;
  get_station_message_1.AddFlag(NLM_F_DUMP);
  GetStationMessage get_station_message_2;
  get_station_message_2.AddFlag(NLM_F_DUMP);
  MockHandler80211 response_handler;
  MockHandlerNetlinkAuxilliary auxilliary_handler;
  MockHandlerNetlinkAck ack_handler;

  // Send the first get station message, which should be sent immediately and
  // trigger a pending dump.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_1, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_1_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Send the second get station message before the replies to the first
  // get station message have been received. This should cause the message
  // to be enqueued for later sending.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).Times(0);
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_2, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_2_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Timeout waiting for responses to the first get station message. This
  // should cause the second get station message to be sent.
  EXPECT_CALL(auxilliary_handler,
              OnErrorHandler(NetlinkManager::kTimeoutWaitingForResponse, _));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  netlink_manager_->OnPendingDumpTimeout();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_2_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Put the state of the singleton back where it was.
  Reset();
}

TEST_F(NetlinkManagerTest, PendingDump_Retry) {
  const int kNumRetries = 1;
  // Create EBUSY netlink error response. Do this manually because
  // ErrorAckMessage does not implement NetlinkMessage::Encode.
  MutableNetlinkPacket received_ebusy_message(kNLMSG_ACK, sizeof(kNLMSG_ACK));
  *received_ebusy_message.GetMutablePayload() =
      ByteString::CreateFromCPUUInt32(EBUSY);

  // The two get station messages (with the dump flag set) will be sent one
  // after another. The second message can only be sent once all replies to the
  // first have been received.
  GetStationMessage get_station_message_1;
  get_station_message_1.AddFlag(NLM_F_DUMP);
  GetStationMessage get_station_message_2;
  get_station_message_2.AddFlag(NLM_F_DUMP);
  MockHandler80211 response_handler;
  MockHandlerNetlinkAuxilliary auxilliary_handler;
  MockHandlerNetlinkAck ack_handler;

  // Send the first get station message, which should be sent immediately and
  // trigger a pending dump.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_1, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_1_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Send the second get station message before the replies to the first
  // get station message have been received. This should cause the message
  // to be enqueued for later sending.
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).Times(0);
  EXPECT_TRUE(netlink_manager_->SendNl80211Message(
      &get_station_message_2, response_handler.on_netlink_message(),
      ack_handler.on_netlink_message(),
      auxilliary_handler.on_netlink_message()));
  uint16_t get_station_message_2_seq_num =
      netlink_socket_->GetLastSequenceNumber();
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Now we receive an EBUSY error response, which should trigger a retry and
  // not invoke the error handler.
  netlink_manager_->pending_messages_.front().retries_left = kNumRetries;
  received_ebusy_message.SetMessageSequence(get_station_message_1_seq_num);
  EXPECT_EQ(kNumRetries,
            netlink_manager_->pending_messages_.front().retries_left);
  EXPECT_CALL(auxilliary_handler, OnErrorHandler(_, _)).Times(0);
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  netlink_manager_->OnNlMessageReceived(&received_ebusy_message);
  // Cancel timeout callback before attempting resend.
  EXPECT_TRUE(netlink_manager_->pending_dump_timeout_callback_.IsCancelled());
  EXPECT_FALSE(netlink_manager_->resend_dump_message_callback_.IsCancelled());
  // Trigger this manually instead of via message loop since it is posted as a
  // delayed task, which base::RunLoop().RunUntilIdle() will not dispatch.
  netlink_manager_->ResendPendingDumpMessage();
  EXPECT_EQ(kNumRetries - 1,
            netlink_manager_->pending_messages_.front().retries_left);
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(2, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_1_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // We receive an EBUSY error response again. Since we have no retries left for
  // this message, the error handler should be invoked, and the next pending
  // message sent.
  received_ebusy_message.ResetConsumedBytes();
  received_ebusy_message.SetMessageSequence(get_station_message_1_seq_num);
  EXPECT_EQ(0, netlink_manager_->pending_messages_.front().retries_left);
  EXPECT_CALL(auxilliary_handler,
              OnErrorHandler(NetlinkManager::kErrorFromKernel, _));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(true));
  netlink_manager_->OnNlMessageReceived(&received_ebusy_message);
  EXPECT_TRUE(netlink_manager_->IsDumpPending());
  EXPECT_EQ(1, netlink_manager_->pending_messages_.size());
  EXPECT_EQ(get_station_message_2_seq_num,
            netlink_manager_->PendingDumpSequenceNumber());

  // Now we receive an EBUSY error response to the second get station message,
  // which should trigger a retry. However, we fail on sending this second retry
  // out on the netlink socket. Since we expended our one retry on this attempt,
  // we should invoke the error handler and declare the dump complete.
  received_ebusy_message.ResetConsumedBytes();
  received_ebusy_message.SetMessageSequence(get_station_message_2_seq_num);
  EXPECT_EQ(1, netlink_manager_->pending_messages_.front().retries_left);
  EXPECT_CALL(auxilliary_handler,
              OnErrorHandler(NetlinkManager::kErrorFromKernel, _));
  EXPECT_CALL(*netlink_socket_, SendMessage(_)).WillOnce(Return(false));
  netlink_manager_->OnNlMessageReceived(&received_ebusy_message);
  // Cancel timeout callback before attempting resend.
  EXPECT_TRUE(netlink_manager_->pending_dump_timeout_callback_.IsCancelled());
  EXPECT_FALSE(netlink_manager_->resend_dump_message_callback_.IsCancelled());
  // Trigger this manually instead of via message loop since it is posted as a
  // delayed task, which base::RunLoop().RunUntilIdle() will not dispatch.
  netlink_manager_->ResendPendingDumpMessage();
  EXPECT_FALSE(netlink_manager_->IsDumpPending());
  EXPECT_TRUE(netlink_manager_->pending_dump_timeout_callback_.IsCancelled());
  EXPECT_TRUE(netlink_manager_->resend_dump_message_callback_.IsCancelled());
  EXPECT_TRUE(netlink_manager_->pending_messages_.empty());

  // Put the state of the singleton back where it was.
  Reset();
}

// Not strictly part of the "public" interface, but part of the
// external interface.
TEST_F(NetlinkManagerTest, OnInvalidRawNlMessageReceived) {
  MockHandlerNetlink message_handler;
  netlink_manager_->AddBroadcastHandler(message_handler.on_netlink_message());

  std::vector<unsigned char> bad_len_message{0x01};  // len should be 32-bits
  std::vector<unsigned char> bad_hdr_message{0x04, 0x00, 0x00,
                                             0x00};  // only len
  std::vector<unsigned char> bad_body_message{
      0x30, 0x00, 0x00, 0x00,  // length
      0x00, 0x00,              // type
      0x00, 0x00,              // flags
      0x00, 0x00, 0x00, 0x00,  // sequence number
      0x00, 0x00, 0x00, 0x00,  // sender port
                               // Body is empty, but should be 32 bytes.
  };

  for (auto message : {bad_len_message, bad_hdr_message, bad_body_message}) {
    EXPECT_CALL(message_handler, OnNetlinkMessage(_)).Times(0);
    InputData data(message.data(), message.size());
    netlink_manager_->OnRawNlMessageReceived(&data);
    Mock::VerifyAndClearExpectations(&message_handler);
  }

  std::vector<unsigned char> good_message{
      0x14, 0x00, 0x00, 0x00,  // length
      0x00, 0x00,              // type
      0x00, 0x00,              // flags
      0x00, 0x00, 0x00, 0x00,  // sequence number
      0x00, 0x00, 0x00, 0x00,  // sender port
      0x00, 0x00, 0x00, 0x00,  // body
  };

  for (auto bad_msg : {bad_len_message, bad_hdr_message, bad_body_message}) {
    // A good message followed by a bad message. This should yield one call
    // to |message_handler|, and one error message.
    std::vector<unsigned char> two_messages(good_message.begin(),
                                            good_message.end());
    two_messages.insert(two_messages.end(), bad_msg.begin(), bad_msg.end());
    EXPECT_CALL(message_handler, OnNetlinkMessage(_)).Times(1);
    InputData data(two_messages.data(), two_messages.size());
    netlink_manager_->OnRawNlMessageReceived(&data);
    Mock::VerifyAndClearExpectations(&message_handler);
  }

  EXPECT_CALL(message_handler, OnNetlinkMessage(_)).Times(0);
  netlink_manager_->OnRawNlMessageReceived(nullptr);
}

}  // namespace shill
