/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2023,  Regents of the University of California,
 *                           Arizona Board of Regents,
 *                           Colorado State University,
 *                           University Pierre & Marie Curie, Sorbonne University,
 *                           Washington University in St. Louis,
 *                           Beijing Institute of Technology,
 *                           The University of Memphis.
 *
 * This file is part of NFD (Named Data Networking Forwarding Daemon).
 * See AUTHORS.md for complete list of NFD authors and contributors.
 *
 * NFD is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation,
 * either version 3 of the License, or (at your option) any later version.
 *
 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "face/generic-link-service.hpp"
#include "face/face.hpp"

#include "tests/test-common.hpp"
#include "tests/key-chain-fixture.hpp"
#include "tests/daemon/global-io-fixture.hpp"
#include "dummy-transport.hpp"

#include <ndn-cxx/lp/empty-value.hpp>
#include <ndn-cxx/lp/prefix-announcement-header.hpp>
#include <ndn-cxx/lp/tags.hpp>

namespace nfd::tests {

using namespace nfd::face;

BOOST_AUTO_TEST_SUITE(Face)

using nfd::Face;

class GenericLinkServiceFixture : public GlobalIoTimeFixture, public KeyChainFixture
{
protected:
  GenericLinkServiceFixture()
  {
    // By default, GenericLinkService is created with default options.
    // Test cases may invoke initialize() with alternate options.
    initialize({});
  }

  void
  initialize(const GenericLinkService::Options& options,
             ssize_t mtu = MTU_UNLIMITED,
             ssize_t sendQueueCapacity = QUEUE_UNSUPPORTED)
  {
    face = make_unique<Face>(make_unique<GenericLinkService>(options),
                             make_unique<DummyTransport>("dummy://", "dummy://",
                                                         ndn::nfd::FACE_SCOPE_NON_LOCAL,
                                                         ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
                                                         ndn::nfd::LINK_TYPE_POINT_TO_POINT,
                                                         mtu, sendQueueCapacity));
    service = static_cast<GenericLinkService*>(face->getLinkService());
    transport = static_cast<DummyTransport*>(face->getTransport());

    face->afterReceiveInterest.connect(
      [this] (const Interest& interest, const EndpointId&) { receivedInterests.push_back(interest); });
    face->afterReceiveData.connect(
      [this] (const Data& data, const EndpointId&) { receivedData.push_back(data); });
    face->afterReceiveNack.connect(
      [this] (const lp::Nack& nack, const EndpointId&) { receivedNacks.push_back(nack); });
  }

  lp::PrefixAnnouncementHeader
  makePrefixAnnHeader(const Name& announcedName)
  {
    return lp::PrefixAnnouncementHeader{signPrefixAnn(makePrefixAnn(announcedName, 1_h),
                                                      m_keyChain, ndn::signingWithSha256())};
  }

protected:
  unique_ptr<Face> face;
  GenericLinkService* service = nullptr;
  DummyTransport* transport = nullptr;
  std::vector<Interest> receivedInterests;
  std::vector<Data> receivedData;
  std::vector<lp::Nack> receivedNacks;
};

BOOST_FIXTURE_TEST_SUITE(TestGenericLinkService, GenericLinkServiceFixture)

BOOST_AUTO_TEST_SUITE(SimpleSendReceive) // send and receive without other fields

BOOST_AUTO_TEST_CASE(SendInterest)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto interest1 = makeInterest("/localhost/test");
  face->sendInterest(*interest1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet interest1pkt(transport->sentPackets.back());
  BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
  BOOST_CHECK(!interest1pkt.has<lp::SequenceField>());
}

BOOST_AUTO_TEST_CASE(SendData)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto data1 = makeData("/localhost/test");
  face->sendData(*data1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet data1pkt(transport->sentPackets.back());
  BOOST_CHECK(data1pkt.has<lp::FragmentField>());
  BOOST_CHECK(!data1pkt.has<lp::SequenceField>());
}

BOOST_AUTO_TEST_CASE(SendDataOverrideMtu)
{
  // Initialize with Options that disables all services and does not override MTU
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  BOOST_CHECK_EQUAL(transport->getMtu(), MTU_UNLIMITED);
  BOOST_CHECK_EQUAL(service->getEffectiveMtu(), MTU_UNLIMITED);
  BOOST_CHECK_EQUAL(face->getMtu(), MTU_UNLIMITED);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MTU_UNLIMITED), false);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MTU_INVALID), false);
  // Attempts to override MTU will fail when transport MTU is unlimited
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(4000), false);

  // Initialize with Options that disables all services and overrides MTU (Transport MTU 8800)
  options.overrideMtu = MIN_MTU;
  initialize(options, ndn::MAX_NDN_PACKET_SIZE);

  // Ensure effective MTU is override value
  BOOST_CHECK_EQUAL(transport->getMtu(), ndn::MAX_NDN_PACKET_SIZE);
  BOOST_CHECK_EQUAL(service->getEffectiveMtu(), MIN_MTU);
  BOOST_CHECK_EQUAL(face->getMtu(), MIN_MTU);

  // Check MTU overrides with Transport MTU finite
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MTU_UNLIMITED), false);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MTU_INVALID), false);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MIN_MTU - 1), false);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(MIN_MTU), true);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(4000), true);
  BOOST_CHECK_EQUAL(service->canOverrideMtuTo(20000), true);

  // Send Data with less than MIN_MTU octets
  auto data1 = makeData("/localhost");
  BOOST_CHECK_LE(data1->wireEncode().size(), MIN_MTU);
  face->sendData(*data1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nOutOverMtu, 0);

  // Send Data with more than MIN_MTU octets
  auto data2 = makeData("/localhost/test/1234567890/1234567890/1234567890/1234567890");
  BOOST_CHECK_GT(data2->wireEncode().size(), MIN_MTU);
  face->sendData(*data2);

  BOOST_CHECK_EQUAL(service->getCounters().nOutData, 2);
  BOOST_CHECK_EQUAL(service->getCounters().nOutOverMtu, 1);

  // Override MTU greater than the Transport's MTU will not be utilized
  options.overrideMtu = 5000;
  initialize(options, 4000);
  BOOST_CHECK_EQUAL(service->getEffectiveMtu(), 4000);
  BOOST_CHECK_EQUAL(face->getMtu(), 4000);
}

BOOST_AUTO_TEST_CASE(SendNack)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto nack1 = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 323),
                        lp::NackReason::NO_ROUTE);
  face->sendNack(nack1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet nack1pkt(transport->sentPackets.back());
  BOOST_CHECK(nack1pkt.has<lp::NackField>());
  BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
  BOOST_CHECK(!nack1pkt.has<lp::SequenceField>());
}

BOOST_AUTO_TEST_CASE(ReceiveBareInterest)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto interest1 = makeInterest("/23Rd9hEiR");
  transport->receivePacket(interest1->wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest1->wireEncode());
}

BOOST_AUTO_TEST_CASE(ReceiveInterest)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto interest1 = makeInterest("/23Rd9hEiR");
  lp::Packet lpPacket;
  lpPacket.set<lp::FragmentField>({interest1->wireEncode().begin(), interest1->wireEncode().end()});
  lpPacket.set<lp::SequenceField>(0); // force LpPacket encoding

  transport->receivePacket(lpPacket.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest1->wireEncode());
}

BOOST_AUTO_TEST_CASE(ReceiveBareData)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto data1 = makeData("/12345678");
  transport->receivePacket(data1->wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInData, 1);
  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  BOOST_CHECK_EQUAL(receivedData.back().wireEncode(), data1->wireEncode());
}

BOOST_AUTO_TEST_CASE(ReceiveData)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto data1 = makeData("/12345689");
  lp::Packet lpPacket;
  lpPacket.set<lp::FragmentField>({data1->wireEncode().begin(), data1->wireEncode().end()});
  lpPacket.set<lp::SequenceField>(0); // force LpPacket encoding

  transport->receivePacket(lpPacket.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInData, 1);
  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  BOOST_CHECK_EQUAL(receivedData.back().wireEncode(), data1->wireEncode());
}

BOOST_AUTO_TEST_CASE(ReceiveNack)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto nack1 = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 323),
                        lp::NackReason::NO_ROUTE);
  lp::Packet lpPacket;
  lpPacket.set<lp::FragmentField>({nack1.getInterest().wireEncode().begin(),
                                   nack1.getInterest().wireEncode().end()});
  lpPacket.set<lp::NackField>(nack1.getHeader());

  transport->receivePacket(lpPacket.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNacks, 1);
  BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
  BOOST_CHECK_EQUAL(receivedNacks.back().getReason(), nack1.getReason());
  BOOST_CHECK_EQUAL(receivedNacks.back().getInterest().wireEncode(), nack1.getInterest().wireEncode());
}

BOOST_AUTO_TEST_CASE(ReceiveIdlePacket)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  lp::Packet lpPacket;
  lpPacket.set<lp::SequenceField>(0);

  transport->receivePacket(lpPacket.wireEncode());

  // IDLE packet should be ignored, but is not an error
  BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0);
  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
  BOOST_CHECK_EQUAL(receivedData.size(), 0);
  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // SimpleSendReceive

BOOST_AUTO_TEST_SUITE(Fragmentation)

BOOST_AUTO_TEST_CASE(FragmentationDisabledExceedMtuDrop)
{
  // Initialize with Options that disable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = false;
  initialize(options);

  transport->setMtu(55);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
  BOOST_CHECK_EQUAL(service->getCounters().nOutOverMtu, 1);
}

// It is possible for some interfaces (e.g., virtual Ethernet) to have their MTU set to zero
// This test case ensures that packets are dropped if the MTU is zero
BOOST_AUTO_TEST_CASE(FragmentationDisabledZeroMtuDrop)
{
  // Initialize with Options that disable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = false;
  initialize(options);

  transport->setMtu(0);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
  BOOST_CHECK_EQUAL(service->getCounters().nOutOverMtu, 1);
}

BOOST_AUTO_TEST_CASE(FragmentationUnlimitedMtu)
{
  // Initialize with Options that enable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = true;
  initialize(options);

  transport->setMtu(MTU_UNLIMITED);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
}

BOOST_AUTO_TEST_CASE(FragmentationUnderMtu)
{
  // Initialize with Options that enable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = true;
  initialize(options);

  transport->setMtu(105);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_EQUAL(transport->sentPackets.size(), 1);
}

BOOST_AUTO_TEST_CASE(FragmentationOverMtu)
{
  // Initialize with Options that enable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = true;
  initialize(options);

  transport->setMtu(60);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_GT(transport->sentPackets.size(), 1);
}

// It is possible for some interfaces (e.g., virtual Ethernet) to have their MTU set to zero
// This test case ensures that packets are dropped if the MTU is zero
BOOST_AUTO_TEST_CASE(FragmentationZeroMtuDrop)
{
  // Initialize with Options that enable fragmentation
  GenericLinkService::Options options;
  options.allowFragmentation = true;
  initialize(options);

  transport->setMtu(0);

  auto data = makeData("/test/data/123456789/987654321/123456789");
  face->sendData(*data);

  BOOST_CHECK_EQUAL(transport->sentPackets.size(), 0);
  BOOST_CHECK_EQUAL(service->getCounters().nFragmentationErrors, 1);
}

BOOST_AUTO_TEST_CASE(ReassembleFragments)
{
  // Initialize with Options that enables reassembly
  GenericLinkService::Options options;
  options.allowReassembly = true;
  initialize(options);

  auto interest = makeInterest(
    "/mt7P130BHXmtLm5dwaY5dpUM6SWYNN2B05g7y3UhsQuLvDdnTWdNnTeEiLuW3FAbJRSG3tzQ0UfaSEgG9rvYHmsKtgPMag1Hj4Tr");
  lp::Packet packet(interest->wireEncode());

  // fragment the packet
  LpFragmenter fragmenter({});
  auto [isOk, frags] = fragmenter.fragmentPacket(packet, 100);
  BOOST_REQUIRE(isOk);
  BOOST_TEST(frags.size() > 1);

  // receive the fragments
  for (ssize_t fragIndex = frags.size() - 1; fragIndex >= 0; --fragIndex) {
    size_t sequence = 1000 + fragIndex;
    frags[fragIndex].add<lp::SequenceField>(sequence);

    transport->receivePacket(frags[fragIndex].wireEncode());

    if (fragIndex > 0) {
      BOOST_CHECK(receivedInterests.empty());
      BOOST_CHECK_EQUAL(service->getCounters().nReassembling, 1);
    }
    else {
      BOOST_CHECK_EQUAL(receivedInterests.size(), 1);
      BOOST_CHECK_EQUAL(receivedInterests.back().wireEncode(), interest->wireEncode());
      BOOST_CHECK_EQUAL(service->getCounters().nReassembling, 0);
    }
  }
}

BOOST_AUTO_TEST_CASE(ReassemblyDisabledDropFragIndex)
{
  // Initialize with Options that disables reassembly
  GenericLinkService::Options options;
  options.allowReassembly = false;
  initialize(options);

  auto interest = makeInterest("/IgFe6NvH");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::FragIndexField>(140);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0); // not an error
  BOOST_CHECK(receivedInterests.empty());
}

BOOST_AUTO_TEST_CASE(ReassemblyDisabledDropFragCount)
{
  // Initialize with Options that disables reassembly
  GenericLinkService::Options options;
  options.allowReassembly = false;
  initialize(options);

  auto interest = makeInterest("/SeGmEjvIVX");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::FragCountField>(276);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 0); // not an error
  BOOST_CHECK(receivedInterests.empty());
}

BOOST_AUTO_TEST_SUITE_END() // Fragmentation

BOOST_AUTO_TEST_SUITE(Reliability)

BOOST_AUTO_TEST_CASE(SendInterest)
{
  // Initialize with Options that enables reliability
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  options.reliabilityOptions.isEnabled = true;
  initialize(options);

  auto interest1 = makeInterest("/localhost/test");
  face->sendInterest(*interest1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutInterests, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet interest1pkt(transport->sentPackets.back());
  BOOST_CHECK(interest1pkt.has<lp::FragmentField>());
  BOOST_CHECK(interest1pkt.has<lp::TxSequenceField>());
}

BOOST_AUTO_TEST_CASE(SendData)
{
  // Initialize with Options that enables reliability
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  options.reliabilityOptions.isEnabled = true;
  initialize(options);

  auto data1 = makeData("/localhost/test");
  face->sendData(*data1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutData, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet data1pkt(transport->sentPackets.back());
  BOOST_CHECK(data1pkt.has<lp::FragmentField>());
  BOOST_CHECK(data1pkt.has<lp::TxSequenceField>());
}

BOOST_AUTO_TEST_CASE(SendNack)
{
  // Initialize with Options that enables reliability
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  options.reliabilityOptions.isEnabled = true;
  initialize(options);

  auto nack1 = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 323),
                        lp::NackReason::NO_ROUTE);
  face->sendNack(nack1);

  BOOST_CHECK_EQUAL(service->getCounters().nOutNacks, 1);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet nack1pkt(transport->sentPackets.back());
  BOOST_CHECK(nack1pkt.has<lp::NackField>());
  BOOST_CHECK(nack1pkt.has<lp::FragmentField>());
  BOOST_CHECK(nack1pkt.has<lp::TxSequenceField>());
}

BOOST_AUTO_TEST_CASE(DropDuplicatePacket)
{
  // Initialize with Options that enables reliability
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  options.reliabilityOptions.isEnabled = true;
  initialize(options);

  Interest interest("/test/prefix");
  lp::Packet pkt1;
  pkt1.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
  pkt1.add<lp::SequenceField>(7);
  pkt1.add<lp::TxSequenceField>(12);
  transport->receivePacket(pkt1.wireEncode());
  BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nDuplicateSequence, 0);

  lp::Packet pkt2;
  pkt2.add<lp::FragmentField>({interest.wireEncode().begin(), interest.wireEncode().end()});
  pkt2.add<lp::SequenceField>(7);
  pkt2.add<lp::TxSequenceField>(13);
  transport->receivePacket(pkt2.wireEncode());
  BOOST_CHECK_EQUAL(service->getCounters().nInInterests, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nDuplicateSequence, 1);
}

BOOST_AUTO_TEST_SUITE_END() // Reliability

// congestion detection and marking
BOOST_AUTO_TEST_SUITE(CongestionMark)

BOOST_AUTO_TEST_CASE(NoCongestion)
{
  GenericLinkService::Options options;
  options.allowCongestionMarking = true;
  options.baseCongestionMarkingInterval = 100_ms;
  initialize(options, MTU_UNLIMITED, 65536);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  auto interest = makeInterest("/12345678");

  // congestion threshold will be 32768 bytes, since min(65536, 65536 / 2) = 32768 bytes

  // no congestion
  transport->setSendQueueLength(0);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet pkt1(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  // no congestion
  transport->setSendQueueLength(32768);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
  lp::Packet pkt2(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
}

BOOST_AUTO_TEST_CASE(CongestionCoDel)
{
  GenericLinkService::Options options;
  options.allowCongestionMarking = true;
  options.baseCongestionMarkingInterval = 100_ms;
  initialize(options, MTU_UNLIMITED, 65536);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  auto interest = makeInterest("/12345678");

  // first congested packet, will not be marked
  transport->setSendQueueLength(65537);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet pkt0(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt0.count<lp::CongestionMarkField>(), 0);
  auto nextMarkTime = time::steady_clock::now() + 100_ms;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);

  time::nanoseconds markingInterval(
        static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                            std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));

  advanceClocks(markingInterval + 1_ms);
  face->sendInterest(*interest);
  lp::Packet pkt1(transport->sentPackets.back());

  // First congestion mark appears after one interval (100 ms)
  BOOST_REQUIRE_EQUAL(pkt1.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt1.get<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 1);

  // advance clock to half of marking interval cycle
  advanceClocks(markingInterval / 2); // 50ms

  // second congested packet, but within marking interval, will not be marked
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
  lp::Packet pkt2(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);

  markingInterval = time::nanoseconds(
      static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                          std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;

  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 1);

  // advance clocks past end of initial interval cycle
  this->advanceClocks((markingInterval / 2) + 1_ms);

  // first congested packet after waiting marking interval, will be marked
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 4);
  lp::Packet pkt3(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt3.get<lp::CongestionMarkField>(), 1);
  markingInterval = time::nanoseconds(
      static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                          std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 2);

  // advance clock partway through current marking interval
  this->advanceClocks(markingInterval - 20_ms);

  // still congested, but within marking interval cycle
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 5);
  lp::Packet pkt4(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt4.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 2);

  // advance clocks past end of current marking interval cycle
  this->advanceClocks(21_ms);

  // still congested, after marking interval cycle
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 6);
  lp::Packet pkt5(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt5.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt5.get<lp::CongestionMarkField>(), 1);
  markingInterval = time::nanoseconds(
    static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                        std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 3);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 3);

  this->advanceClocks(1_ms);

  // still congested, but within marking interval cycle
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 7);
  lp::Packet pkt6(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt6.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 3);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 3);

  this->advanceClocks(markingInterval);

  // still congested, after marking interval cycle
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 8);
  lp::Packet pkt7(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt7.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt7.get<lp::CongestionMarkField>(), 1);
  markingInterval = time::nanoseconds(
    static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                        std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 4);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);

  // no more congestion
  transport->setSendQueueLength(30000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 9);
  lp::Packet pkt8(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt8.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);

  this->advanceClocks(50_ms);

  // send queue congested again, but can't mark packet because within one full interval of last mark
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 10);
  lp::Packet pkt9(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt9.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  markingInterval = time::nanoseconds(
      static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                          std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime = time::steady_clock::now() + markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 4);

  // advance clock past full 100ms interval since last mark
  this->advanceClocks(markingInterval + 2_ms);
  BOOST_CHECK_GT(time::steady_clock::now(), nextMarkTime);

  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 11);
  lp::Packet pkt10(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt10.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt10.get<lp::CongestionMarkField>(), 1);
  markingInterval = time::nanoseconds(
        static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                            std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 5);

  // advance clock partway through 100ms marking interval
  this->advanceClocks(50_ms);

  // not marked since within 100ms window before can mark again
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 12);
  lp::Packet pkt11(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt11.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 1);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 5);

  // advance clocks past m_nextMarkTime
  this->advanceClocks(51_ms);

  // markable packet, queue length still above threshold
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 13);
  lp::Packet pkt12(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt12.count<lp::CongestionMarkField>(), 1);
  BOOST_CHECK_EQUAL(pkt12.get<lp::CongestionMarkField>(), 1);
  markingInterval = time::nanoseconds(
    static_cast<time::nanoseconds::rep>(options.baseCongestionMarkingInterval.count() /
                                        std::sqrt(service->m_nMarkedSinceInMarkingState + 1)));
  nextMarkTime += markingInterval;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 2);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);

  // no more congestion
  transport->setSendQueueLength(10000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 14);
  lp::Packet pkt13(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt13.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);

  // advance clocks past one full interval since last mark
  this->advanceClocks(102_ms);

  // start congestion again
  transport->setSendQueueLength(66000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 15);
  lp::Packet pkt14(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt14.count<lp::CongestionMarkField>(), 0);
  nextMarkTime = time::steady_clock::now() + 100_ms;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);

  // no more congestion, cancel marking interval
  transport->setSendQueueLength(5000);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 16);
  lp::Packet pkt15(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt15.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 6);
}

BOOST_AUTO_TEST_CASE(DefaultThreshold)
{
  GenericLinkService::Options options;
  options.allowCongestionMarking = true;
  options.baseCongestionMarkingInterval = 100_ms;
  initialize(options, MTU_UNLIMITED, QUEUE_UNSUPPORTED);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  auto interest = makeInterest("/12345678");

  // congestion threshold will be 65536 bytes, since the transport reports that it cannot measure
  // the queue capacity

  // no congestion
  transport->setSendQueueLength(0);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet pkt1(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt1.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  // no congestion
  transport->setSendQueueLength(65536);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 2);
  lp::Packet pkt2(transport->sentPackets.back());
  BOOST_CHECK_EQUAL(pkt2.count<lp::CongestionMarkField>(), 0);
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, time::steady_clock::time_point::max());
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);

  // first congested (not marked yet) packet
  transport->setSendQueueLength(65537);
  face->sendInterest(*interest);
  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 3);
  lp::Packet pkt3(transport->sentPackets.back());
  BOOST_REQUIRE_EQUAL(pkt3.count<lp::CongestionMarkField>(), 0);
  auto nextMarkTime = time::steady_clock::now() + 100_ms;
  BOOST_CHECK_EQUAL(service->m_nextMarkTime, nextMarkTime);
  BOOST_CHECK_EQUAL(service->m_nMarkedSinceInMarkingState, 0);
  BOOST_CHECK_EQUAL(service->getCounters().nCongestionMarked, 0);
}

BOOST_AUTO_TEST_SUITE_END() // CongestionMark

BOOST_AUTO_TEST_SUITE(LpFields)

BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceId)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::NextHopFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  auto tag = receivedInterests.back().getTag<lp::NextHopFaceIdTag>();
  BOOST_REQUIRE(tag != nullptr);
  BOOST_CHECK_EQUAL(*tag, 1000);
}

BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDisabled)
{
  // Initialize with Options that disables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::NextHopFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_CHECK(receivedInterests.empty());
}

BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDropData)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  packet.set<lp::NextHopFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedData.empty());
}

BOOST_AUTO_TEST_CASE(ReceiveNextHopFaceIdDropNack)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                       lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>({nack.getInterest().wireEncode().begin(),
                                 nack.getInterest().wireEncode().end()});
  packet.set<lp::NackField>(nack.getHeader());
  packet.set<lp::NextHopFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedNacks.empty());
}

BOOST_AUTO_TEST_CASE(ReceiveCachePolicy)
{
  // Initialize with Options that disables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);
  // CachePolicy is unprivileged and does not require allowLocalFields option.

  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  packet.set<lp::CachePolicyField>(lp::CachePolicy().setPolicy(lp::CachePolicyType::NO_CACHE));

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  auto tag = receivedData.back().getTag<lp::CachePolicyTag>();
  BOOST_REQUIRE(tag != nullptr);
  BOOST_CHECK_EQUAL(tag->get().getPolicy(), lp::CachePolicyType::NO_CACHE);
}

BOOST_AUTO_TEST_CASE(ReceiveCachePolicyDropInterest)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  lp::CachePolicy policy;
  policy.setPolicy(lp::CachePolicyType::NO_CACHE);
  packet.set<lp::CachePolicyField>(policy);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedInterests.empty());
}

BOOST_AUTO_TEST_CASE(ReceiveCachePolicyDropNack)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  lp::Packet packet(nack.getInterest().wireEncode());
  packet.set<lp::NackField>(nack.getHeader());
  lp::CachePolicy policy;
  policy.setPolicy(lp::CachePolicyType::NO_CACHE);
  packet.set<lp::CachePolicyField>(policy);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedNacks.empty());
}

BOOST_AUTO_TEST_CASE(SendIncomingFaceId)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));

  face->sendInterest(*interest);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_REQUIRE(sent.has<lp::IncomingFaceIdField>());
  BOOST_CHECK_EQUAL(sent.get<lp::IncomingFaceIdField>(), 1000);
}

BOOST_AUTO_TEST_CASE(SendIncomingFaceIdDisabled)
{
  // Initialize with Options that disables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto interest = makeInterest("/12345678");
  interest->setTag(make_shared<lp::IncomingFaceIdTag>(1000));

  face->sendInterest(*interest);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_CHECK(!sent.has<lp::IncomingFaceIdField>());
}

BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreInterest)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::IncomingFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  BOOST_CHECK(receivedInterests.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
}

BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreData)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  auto data = makeData("/z1megUh9Bj");
  lp::Packet packet(data->wireEncode());
  packet.set<lp::IncomingFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  BOOST_CHECK(receivedData.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
}

BOOST_AUTO_TEST_CASE(ReceiveIncomingFaceIdIgnoreNack)
{
  // Initialize with Options that enables local fields
  GenericLinkService::Options options;
  options.allowLocalFields = true;
  initialize(options);

  lp::Nack nack = makeNack(*makeInterest("/TPAhdiHz", false, std::nullopt, 278),
                           lp::NackReason::CONGESTION);
  lp::Packet packet(nack.getInterest().wireEncode());
  packet.set<lp::NackField>(nack.getHeader());
  packet.set<lp::IncomingFaceIdField>(1000);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
  BOOST_CHECK(receivedNacks.back().getTag<lp::IncomingFaceIdTag>() == nullptr);
}

BOOST_AUTO_TEST_CASE(SendCongestionMarkInterest)
{
  auto interest = makeInterest("/12345678");
  interest->setTag(make_shared<lp::CongestionMarkTag>(1));

  face->sendInterest(*interest);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
  BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), 1);
}

BOOST_AUTO_TEST_CASE(SendCongestionMarkData)
{
  auto data = makeData("/12345678");
  data->setTag(make_shared<lp::CongestionMarkTag>(0));

  face->sendData(*data);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
  BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), 0);
}

BOOST_AUTO_TEST_CASE(SendCongestionMarkNack)
{
  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  nack.setTag(make_shared<lp::CongestionMarkTag>(std::numeric_limits<uint64_t>::max()));

  face->sendNack(nack);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_REQUIRE(sent.has<lp::CongestionMarkField>());
  BOOST_CHECK_EQUAL(sent.get<lp::CongestionMarkField>(), std::numeric_limits<uint64_t>::max());
}

BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkInterest)
{
  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::CongestionMarkField>(1);

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  auto tag = receivedInterests.back().getTag<lp::CongestionMarkTag>();
  BOOST_REQUIRE(tag != nullptr);
  BOOST_CHECK_EQUAL(*tag, 1);
}

BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkData)
{
  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  packet.set<lp::CongestionMarkField>(1);

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  auto tag = receivedData.back().getTag<lp::CongestionMarkTag>();
  BOOST_REQUIRE(tag != nullptr);
  BOOST_CHECK_EQUAL(*tag, 1);
}

BOOST_AUTO_TEST_CASE(ReceiveCongestionMarkNack)
{
  auto nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                       lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>({nack.getInterest().wireEncode().begin(),
                                 nack.getInterest().wireEncode().end()});
  packet.set<lp::NackField>(nack.getHeader());
  packet.set<lp::CongestionMarkField>(1);

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedNacks.size(), 1);
  auto tag = receivedNacks.back().getTag<lp::CongestionMarkTag>();
  BOOST_REQUIRE(tag != nullptr);
  BOOST_CHECK_EQUAL(*tag, 1);
}

BOOST_AUTO_TEST_CASE(SendNonDiscovery)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  interest->setTag(make_shared<lp::NonDiscoveryTag>(lp::EmptyValue{}));

  face->sendInterest(*interest);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_CHECK(sent.has<lp::NonDiscoveryField>());
}

BOOST_AUTO_TEST_CASE(SendNonDiscoveryDisabled)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = false;
  initialize(options);

  auto interest = makeInterest("/12345678");
  interest->setTag(make_shared<lp::NonDiscoveryTag>(lp::EmptyValue{}));

  face->sendInterest(*interest);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_CHECK(!sent.has<lp::NonDiscoveryField>());
}

BOOST_AUTO_TEST_CASE(ReceiveNonDiscovery)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedInterests.size(), 1);
  auto tag = receivedInterests.back().getTag<lp::NonDiscoveryTag>();
  BOOST_CHECK(tag != nullptr);
}

BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDisabled)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = false;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_CHECK_EQUAL(receivedInterests.size(), 1);
  auto tag = receivedInterests.back().getTag<lp::NonDiscoveryTag>();
  BOOST_CHECK(tag == nullptr);
}

BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDropData)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedData.empty());
}

BOOST_AUTO_TEST_CASE(ReceiveNonDiscoveryDropNack)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                       lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>({nack.getInterest().wireEncode().begin(),
                                 nack.getInterest().wireEncode().end()});
  packet.set<lp::NackField>(nack.getHeader());
  packet.set<lp::NonDiscoveryField>(lp::EmptyValue{});

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedNacks.empty());
}

BOOST_AUTO_TEST_CASE(SendPrefixAnnouncement)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto data = makeData("/12345678");
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  data->setTag(make_shared<lp::PrefixAnnouncementTag>(pah));

  face->sendData(*data);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_CHECK(sent.has<lp::PrefixAnnouncementField>());
}

BOOST_AUTO_TEST_CASE(SendPrefixAnnouncementDisabled)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = false;
  initialize(options);

  auto data = makeData("/12345678");
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  data->setTag(make_shared<lp::PrefixAnnouncementTag>(pah));

  face->sendData(*data);

  BOOST_REQUIRE_EQUAL(transport->sentPackets.size(), 1);
  lp::Packet sent(transport->sentPackets.back());
  BOOST_CHECK(!sent.has<lp::PrefixAnnouncementField>());
}

BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncement)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  packet.set<lp::PrefixAnnouncementField>(pah);

  transport->receivePacket(packet.wireEncode());

  BOOST_REQUIRE_EQUAL(receivedData.size(), 1);
  auto tag = receivedData.back().getTag<lp::PrefixAnnouncementTag>();
  BOOST_CHECK_EQUAL(tag->get().getPrefixAnn()->getAnnouncedName(), "/local/ndn/prefix");
}

BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDisabled)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = false;
  initialize(options);

  auto data = makeData("/12345678");
  lp::Packet packet(data->wireEncode());
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  packet.set<lp::PrefixAnnouncementField>(pah);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 0); // not an error
  BOOST_CHECK_EQUAL(receivedData.size(), 1);
  auto tag = receivedData.back().getTag<lp::PrefixAnnouncementTag>();
  BOOST_CHECK(tag == nullptr);
}

BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDropInterest)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto interest = makeInterest("/12345678");
  lp::Packet packet(interest->wireEncode());
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  packet.set<lp::PrefixAnnouncementField>(pah);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedInterests.empty());
}

BOOST_AUTO_TEST_CASE(ReceivePrefixAnnouncementDropNack)
{
  GenericLinkService::Options options;
  options.allowSelfLearning = true;
  initialize(options);

  auto nack = makeNack(*makeInterest("/localhost/test", false, std::nullopt, 123),
                       lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>({nack.getInterest().wireEncode().begin(),
                                 nack.getInterest().wireEncode().end()});
  packet.set<lp::NackField>(nack.getHeader());
  auto pah = makePrefixAnnHeader("/local/ndn/prefix");
  packet.set<lp::PrefixAnnouncementField>(pah);

  transport->receivePacket(packet.wireEncode());

  BOOST_CHECK_EQUAL(service->getCounters().nInNetInvalid, 1);
  BOOST_CHECK(receivedNacks.empty());
}

BOOST_AUTO_TEST_SUITE_END() // LpFields

BOOST_AUTO_TEST_SUITE(Malformed) // receive malformed packets

BOOST_AUTO_TEST_CASE(WrongTlvType)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto packet = ndn::encoding::makeEmptyBlock(tlv::Name);
  transport->receivePacket(packet);

  BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
  BOOST_CHECK_EQUAL(receivedData.size(), 0);
  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
}

BOOST_AUTO_TEST_CASE(Unparsable)
{
  // Initialize with Options that disables all services
  GenericLinkService::Options options;
  options.allowLocalFields = false;
  initialize(options);

  auto packet = ndn::encoding::makeStringBlock(lp::tlv::LpPacket, "x");
  BOOST_CHECK_THROW(packet.parse(), tlv::Error);
  transport->receivePacket(packet);

  BOOST_CHECK_EQUAL(service->getCounters().nInLpInvalid, 1);
  BOOST_CHECK_EQUAL(receivedInterests.size(), 0);
  BOOST_CHECK_EQUAL(receivedData.size(), 0);
  BOOST_CHECK_EQUAL(receivedNacks.size(), 0);
}

BOOST_AUTO_TEST_SUITE_END() // Malformed

BOOST_AUTO_TEST_SUITE_END() // TestGenericLinkService
BOOST_AUTO_TEST_SUITE_END() // Face

} // namespace nfd::tests
