/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2017,  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 "nfdc/face-module.hpp"

#include "execute-command-fixture.hpp"
#include "status-fixture.hpp"

namespace nfd {
namespace tools {
namespace nfdc {
namespace tests {

using ndn::nfd::FaceQueryFilter;

BOOST_AUTO_TEST_SUITE(Nfdc)
BOOST_AUTO_TEST_SUITE(TestFaceModule)

BOOST_FIXTURE_TEST_SUITE(ListCommand, ExecuteCommandFixture)

const std::string NONQUERY_OUTPUT =
  "faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
    " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
    " flags={non-local permanent multi-access}\n"
  "faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
    " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
    " flags={local on-demand point-to-point local-fields}\n";

BOOST_AUTO_TEST_CASE(NormalNonQuery)
{
  this->processInterest = [this] (const Interest& interest) {
    FaceStatus payload1;
    payload1.setFaceId(134)
            .setRemoteUri("udp4://233.252.0.4:6363")
            .setLocalUri("udp4://192.0.2.1:6363")
            .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
            .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
            .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
            .setNInInterests(22562)
            .setNInDatas(22031)
            .setNInNacks(63)
            .setNOutInterests(30121)
            .setNOutDatas(20940)
            .setNOutNacks(1218)
            .setNInBytes(2522915)
            .setNOutBytes(1353592);
    FaceStatus payload2;
    payload2.setFaceId(745)
            .setRemoteUri("fd://75")
            .setLocalUri("unix:///var/run/nfd.sock")
            .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
            .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
            .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
            .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true)
            .setNInInterests(18998)
            .setNInDatas(26701)
            .setNInNacks(147)
            .setNOutInterests(34779)
            .setNOutDatas(17028)
            .setNOutNacks(1176)
            .setNInBytes(4672308)
            .setNOutBytes(8957187);
    this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
  };

  this->execute("face list");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal(NONQUERY_OUTPUT));
  BOOST_CHECK(err.is_empty());
}

const std::string QUERY_OUTPUT =
  "faceid=177 remote=tcp4://53.239.9.114:6363 local=tcp4://164.0.31.106:20396"
    " counters={in={2325i 1110d 79n 4716834B} out={2278i 485d 841n 308108B}}"
    " flags={non-local persistent point-to-point}\n";

BOOST_AUTO_TEST_CASE(NormalQuery)
{
  this->processInterest = [this] (const Interest& interest) {
    BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
    BOOST_CHECK_EQUAL(interest.getName().size(), 5);
    FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
    FaceQueryFilter expectedFilter;
    expectedFilter.setRemoteUri("tcp4://53.239.9.114:6363")
                  .setLocalUri("tcp4://164.0.31.106:20396")
                  .setUriScheme("tcp4");
    BOOST_CHECK_EQUAL(filter, expectedFilter);

    FaceStatus payload;
    payload.setFaceId(177)
           .setRemoteUri("tcp4://53.239.9.114:6363")
           .setLocalUri("tcp4://164.0.31.106:20396")
           .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
           .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
           .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
           .setNInInterests(2325)
           .setNInDatas(1110)
           .setNInNacks(79)
           .setNOutInterests(2278)
           .setNOutDatas(485)
           .setNOutNacks(841)
           .setNInBytes(4716834)
           .setNOutBytes(308108);
    this->sendDataset(interest.getName(), payload);
  };

  this->execute("face list tcp://53.239.9.114 scheme tcp4 local tcp://164.0.31.106:20396");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal(QUERY_OUTPUT));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(NotFound)
{
  this->processInterest = [this] (const Interest& interest) {
    this->sendEmptyDataset(interest.getName());
  };

  this->execute("face list scheme udp6");
  BOOST_CHECK_EQUAL(exitCode, 3);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Face not found\n"));
}

BOOST_AUTO_TEST_CASE(Error)
{
  this->processInterest = nullptr; // no response

  this->execute("face list local udp4://31.67.17.2:6363");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
}

BOOST_AUTO_TEST_SUITE_END() // ListCommand

BOOST_FIXTURE_TEST_SUITE(ShowCommand, ExecuteCommandFixture)

const std::string NORMAL_OUTPUT = std::string(R"TEXT(
  faceid=256
  remote=udp4://84.67.35.111:6363
   local=udp4://79.91.49.215:6363
counters={in={28975i 28232d 212n 13307258B} out={19525i 30993d 1038n 6231946B}}
   flags={non-local on-demand point-to-point}
)TEXT").substr(1);

BOOST_AUTO_TEST_CASE(Normal)
{
  this->processInterest = [this] (const Interest& interest) {
    BOOST_CHECK(Name("/localhost/nfd/faces/query").isPrefixOf(interest.getName()));
    BOOST_CHECK_EQUAL(interest.getName().size(), 5);
    FaceQueryFilter filter(interest.getName().at(4).blockFromValue());
    BOOST_CHECK_EQUAL(filter, FaceQueryFilter().setFaceId(256));

    FaceStatus payload;
    payload.setFaceId(256)
           .setRemoteUri("udp4://84.67.35.111:6363")
           .setLocalUri("udp4://79.91.49.215:6363")
           .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
           .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
           .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
           .setNInInterests(28975)
           .setNInDatas(28232)
           .setNInNacks(212)
           .setNOutInterests(19525)
           .setNOutDatas(30993)
           .setNOutNacks(1038)
           .setNInBytes(13307258)
           .setNOutBytes(6231946);

    this->sendDataset(interest.getName(), payload);
  };

  this->execute("face show 256");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal(NORMAL_OUTPUT));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(NotFound)
{
  this->processInterest = [this] (const Interest& interest) {
    this->sendEmptyDataset(interest.getName());
  };

  this->execute("face show 256");
  BOOST_CHECK_EQUAL(exitCode, 3);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Face not found\n"));
}

BOOST_AUTO_TEST_CASE(Error)
{
  this->processInterest = nullptr; // no response

  this->execute("face show 256");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
}

BOOST_AUTO_TEST_SUITE_END() // ShowCommand

class ExecuteFaceCreateCommandFixture : public ExecuteCommandFixture
{
protected:
  void
  respond409(const Interest& interest, FacePersistency persistency)
  {
    MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
    ControlParameters body;
    body.setFaceId(1172)
        .setUri("udp4://100.77.30.65:6363")
        .setFacePersistency(persistency)
        .setFlags(0);
    this->failCommand(interest, 409, "conflict-409", body);
  }
};

BOOST_FIXTURE_TEST_SUITE(CreateCommand, ExecuteFaceCreateCommandFixture)

BOOST_AUTO_TEST_CASE(Creating)
{
  this->processInterest = [this] (const Interest& interest) {
    ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/create");
    BOOST_REQUIRE(req.hasUri());
    BOOST_CHECK_EQUAL(req.getUri(), "udp4://159.242.33.78:6363");
    BOOST_REQUIRE(req.hasFacePersistency());
    BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);

    ControlParameters resp;
    resp.setFaceId(2130)
        .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT);
    this->succeedCommand(interest, resp);
  };

  this->execute("face create udp://159.242.33.78");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-created id=2130 remote=udp4://159.242.33.78:6363 persistency=persistent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(UpgradingPersistency)
{
  bool hasUpdateCommand = false;
  this->processInterest = [this, &hasUpdateCommand] (const Interest& interest) {
    if (parseCommand(interest, "/localhost/nfd/faces/create")) {
      this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
      return;
    }

    ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
    hasUpdateCommand = true;
    BOOST_REQUIRE(req.hasFaceId());
    BOOST_CHECK_EQUAL(req.getFaceId(), 1172);
    BOOST_REQUIRE(req.hasFacePersistency());
    BOOST_CHECK_EQUAL(req.getFacePersistency(), FacePersistency::FACE_PERSISTENCY_PERSISTENT);
    BOOST_CHECK(!req.hasFlags());

    ControlParameters resp;
    resp.setFaceId(1172)
        .setFacePersistency(FacePersistency::FACE_PERSISTENCY_PERSISTENT)
        .setFlags(0);
    this->succeedCommand(interest, resp);
  };

  this->execute("face create udp://100.77.30.65");
  BOOST_CHECK(hasUpdateCommand);
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-updated id=1172 remote=udp4://100.77.30.65:6363 persistency=persistent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(NotDowngradingPersistency)
{
  this->processInterest = [this] (const Interest& interest) {
    this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERMANENT);
    // no command other than faces/create is expected
  };

  this->execute("face create udp://100.77.30.65");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-exists id=1172 remote=udp4://100.77.30.65:6363 persistency=permanent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(SamePersistency)
{
  this->processInterest = [this] (const Interest& interest) {
    this->respond409(interest, FacePersistency::FACE_PERSISTENCY_PERSISTENT);
    // no command other than faces/create is expected
  };

  this->execute("face create udp://100.77.30.65");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-exists id=1172 remote=udp4://100.77.30.65:6363 persistency=persistent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(ErrorCreate)
{
  this->processInterest = nullptr; // no response

  this->execute("face create udp://159.242.33.78");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when creating face: request timed out\n"));
}

BOOST_AUTO_TEST_CASE(ErrorConflict)
{
  // Current NFD will not report a 409-conflict with a different remote FaceUri, but this is
  // allowed by FaceMgmt protocol and nfdc should not attempt to upgrade persistency in this case.

  this->processInterest = [this] (const Interest& interest) {
    // conflict with udp4://100.77.30.65:6363
    this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
  };

  this->execute("face create udp://20.53.73.45");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 409 when creating face: conflict-409\n"));
}

BOOST_AUTO_TEST_CASE(ErrorUpdate)
{
  this->processInterest = [this] (const Interest& interest) {
    if (parseCommand(interest, "/localhost/nfd/faces/create")) {
      this->respond409(interest, FacePersistency::FACE_PERSISTENCY_ON_DEMAND);
      return;
    }

    MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/update");
    // no response to faces/update
  };

  this->execute("face create udp://100.77.30.65");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when upgrading face persistency: request timed out\n"));
}

BOOST_AUTO_TEST_SUITE_END() // CreateCommand

BOOST_FIXTURE_TEST_SUITE(DestroyCommand, ExecuteCommandFixture)

BOOST_AUTO_TEST_CASE(NormalByFaceId)
{
  this->processInterest = [this] (const Interest& interest) {
    if (this->respondFaceQuery(interest)) {
      return;
    }

    ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
    BOOST_REQUIRE(req.hasFaceId());
    BOOST_CHECK_EQUAL(req.getFaceId(), 10156);

    ControlParameters resp;
    resp.setFaceId(10156);
    this->succeedCommand(interest, resp);
  };

  this->execute("face destroy 10156");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-destroyed id=10156 local=tcp4://151.26.163.27:22967 "
                           "remote=tcp4://198.57.27.40:6363 persistency=persistent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(NormalByFaceUri)
{
  this->processInterest = [this] (const Interest& interest) {
    if (this->respondFaceQuery(interest)) {
      return;
    }

    ControlParameters req = MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
    BOOST_REQUIRE(req.hasFaceId());
    BOOST_CHECK_EQUAL(req.getFaceId(), 2249);

    ControlParameters resp;
    resp.setFaceId(2249);
    this->succeedCommand(interest, resp);
  };

  this->execute("face destroy tcp://32.121.182.82");
  BOOST_CHECK_EQUAL(exitCode, 0);
  BOOST_CHECK(out.is_equal("face-destroyed id=2249 local=tcp4://30.99.87.98:31414 "
                           "remote=tcp4://32.121.182.82:6363 persistency=persistent\n"));
  BOOST_CHECK(err.is_empty());
}

BOOST_AUTO_TEST_CASE(FaceNotExist)
{
  this->processInterest = [this] (const Interest& interest) {
    BOOST_CHECK(this->respondFaceQuery(interest));
  };

  this->execute("face destroy 23728");
  BOOST_CHECK_EQUAL(exitCode, 3);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Face not found\n"));
}

BOOST_AUTO_TEST_CASE(Ambiguous)
{
  this->processInterest = [this] (const Interest& interest) {
    BOOST_CHECK(this->respondFaceQuery(interest));
  };

  this->execute("face destroy udp4://225.131.75.231:56363");
  BOOST_CHECK_EQUAL(exitCode, 5);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Multiple faces match specified remote FaceUri. "
                           "Re-run the command with a FaceId: "
                           "6720 (local=udp4://202.83.168.28:56363), "
                           "31066 (local=udp4://25.90.26.32:56363)\n"));
}

BOOST_AUTO_TEST_CASE(ErrorCanonization)
{
  this->execute("face destroy udp6://32.38.164.64:10445");
  BOOST_CHECK_EQUAL(exitCode, 4);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error during remote FaceUri canonization: "
                           "No endpoints match the specified address selector\n"));
}

BOOST_AUTO_TEST_CASE(ErrorDataset)
{
  this->processInterest = nullptr; // no response to dataset or command

  this->execute("face destroy udp://159.242.33.78");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when querying face: Timeout\n"));
}

BOOST_AUTO_TEST_CASE(ErrorCommand)
{
  this->processInterest = [this] (const Interest& interest) {
    if (this->respondFaceQuery(interest)) {
      return;
    }

    MOCK_NFD_MGMT_REQUIRE_COMMAND_IS("/localhost/nfd/faces/destroy");
    // no response to command
  };

  this->execute("face destroy 10156");
  BOOST_CHECK_EQUAL(exitCode, 1);
  BOOST_CHECK(out.is_empty());
  BOOST_CHECK(err.is_equal("Error 10060 when destroying face: request timed out\n"));
}

BOOST_AUTO_TEST_SUITE_END() // DestroyCommand

const std::string STATUS_XML = stripXmlSpaces(R"XML(
  <faces>
    <face>
      <faceId>134</faceId>
      <remoteUri>udp4://233.252.0.4:6363</remoteUri>
      <localUri>udp4://192.0.2.1:6363</localUri>
      <faceScope>non-local</faceScope>
      <facePersistency>permanent</facePersistency>
      <linkType>multi-access</linkType>
      <flags/>
      <packetCounters>
        <incomingPackets>
          <nInterests>22562</nInterests>
          <nDatas>22031</nDatas>
          <nNacks>63</nNacks>
        </incomingPackets>
        <outgoingPackets>
          <nInterests>30121</nInterests>
          <nDatas>20940</nDatas>
          <nNacks>1218</nNacks>
        </outgoingPackets>
      </packetCounters>
      <byteCounters>
        <incomingBytes>2522915</incomingBytes>
        <outgoingBytes>1353592</outgoingBytes>
      </byteCounters>
    </face>
    <face>
      <faceId>745</faceId>
      <remoteUri>fd://75</remoteUri>
      <localUri>unix:///var/run/nfd.sock</localUri>
      <faceScope>local</faceScope>
      <facePersistency>on-demand</facePersistency>
      <linkType>point-to-point</linkType>
      <flags>
        <localFieldsEnabled/>
      </flags>
      <packetCounters>
        <incomingPackets>
          <nInterests>18998</nInterests>
          <nDatas>26701</nDatas>
          <nNacks>147</nNacks>
        </incomingPackets>
        <outgoingPackets>
          <nInterests>34779</nInterests>
          <nDatas>17028</nDatas>
          <nNacks>1176</nNacks>
        </outgoingPackets>
      </packetCounters>
      <byteCounters>
        <incomingBytes>4672308</incomingBytes>
        <outgoingBytes>8957187</outgoingBytes>
      </byteCounters>
    </face>
  </faces>
)XML");

const std::string STATUS_TEXT =
  "Faces:\n"
  "  faceid=134 remote=udp4://233.252.0.4:6363 local=udp4://192.0.2.1:6363"
    " counters={in={22562i 22031d 63n 2522915B} out={30121i 20940d 1218n 1353592B}}"
    " flags={non-local permanent multi-access}\n"
  "  faceid=745 remote=fd://75 local=unix:///var/run/nfd.sock"
    " counters={in={18998i 26701d 147n 4672308B} out={34779i 17028d 1176n 8957187B}}"
    " flags={local on-demand point-to-point local-fields}\n";

BOOST_FIXTURE_TEST_CASE(Status, StatusFixture<FaceModule>)
{
  this->fetchStatus();
  FaceStatus payload1;
  payload1.setFaceId(134)
          .setRemoteUri("udp4://233.252.0.4:6363")
          .setLocalUri("udp4://192.0.2.1:6363")
          .setFaceScope(ndn::nfd::FACE_SCOPE_NON_LOCAL)
          .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERMANENT)
          .setLinkType(ndn::nfd::LINK_TYPE_MULTI_ACCESS)
          .setNInInterests(22562)
          .setNInDatas(22031)
          .setNInNacks(63)
          .setNOutInterests(30121)
          .setNOutDatas(20940)
          .setNOutNacks(1218)
          .setNInBytes(2522915)
          .setNOutBytes(1353592);
  FaceStatus payload2;
  payload2.setFaceId(745)
          .setRemoteUri("fd://75")
          .setLocalUri("unix:///var/run/nfd.sock")
          .setFaceScope(ndn::nfd::FACE_SCOPE_LOCAL)
          .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_ON_DEMAND)
          .setLinkType(ndn::nfd::LINK_TYPE_POINT_TO_POINT)
          .setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, true)
          .setNInInterests(18998)
          .setNInDatas(26701)
          .setNInNacks(147)
          .setNOutInterests(34779)
          .setNOutDatas(17028)
          .setNOutNacks(1176)
          .setNInBytes(4672308)
          .setNOutBytes(8957187);
  this->sendDataset("/localhost/nfd/faces/list", payload1, payload2);
  this->prepareStatusOutput();

  BOOST_CHECK(statusXml.is_equal(STATUS_XML));
  BOOST_CHECK(statusText.is_equal(STATUS_TEXT));
}

BOOST_AUTO_TEST_SUITE_END() // TestFaceModule
BOOST_AUTO_TEST_SUITE_END() // Nfdc

} // namespace tests
} // namespace nfdc
} // namespace tools
} // namespace nfd
