/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2014-2022,  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 {
namespace face {
namespace tests {

using namespace nfd::tests;

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, 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>(std::make_pair(
    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>(std::make_pair(
    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);

  lp::Nack nack1 = makeNack(*makeInterest("/localhost/test", false, nullopt, 323),
                            lp::NackReason::NO_ROUTE);
  lp::Packet lpPacket;
  lpPacket.set<lp::FragmentField>(std::make_pair(
    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({});
  size_t mtu = 100;
  bool isOk = false;
  std::vector<lp::Packet> frags;
  std::tie(isOk, frags) = fragmenter.fragmentPacket(packet, mtu);
  BOOST_REQUIRE(isOk);
  BOOST_CHECK_GT(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, 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::TimePoint::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::TimePoint::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::TimePoint::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::TimePoint::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);
  time::steady_clock::TimePoint 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::TimePoint::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::TimePoint::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::TimePoint::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::TimePoint::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::TimePoint::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::TimePoint::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);
  time::steady_clock::TimePoint 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);

  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>(std::make_pair(
    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, 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, 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, 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)
{
  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>(std::make_pair(
    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);

  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>(std::make_pair(
    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);

  lp::Nack nack = makeNack(*makeInterest("/localhost/test", false, nullopt, 123),
                           lp::NackReason::NO_ROUTE);
  lp::Packet packet;
  packet.set<lp::FragmentField>(std::make_pair(
    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 tests
} // namespace face
} // namespace nfd
