mgmt: support LpReliability flag in faces/create and faces/update

refs #4003

Change-Id: Iddf94ea55c630b038187c2503783591b118230ec
diff --git a/tests/daemon/face/ethernet-channel.t.cpp b/tests/daemon/face/ethernet-channel.t.cpp
index 78f5015..3cb705a 100644
--- a/tests/daemon/face/ethernet-channel.t.cpp
+++ b/tests/daemon/face/ethernet-channel.t.cpp
@@ -78,6 +78,7 @@
   shared_ptr<nfd::Face> face;
   channel->connect({0x00, 0x00, 0x5e, 0x00, 0x53, 0x5e},
                    ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+                   false,
                    [&face] (const shared_ptr<nfd::Face>& newFace) {
                      BOOST_REQUIRE(newFace != nullptr);
                      face = newFace;
diff --git a/tests/daemon/face/ethernet-factory.t.cpp b/tests/daemon/face/ethernet-factory.t.cpp
index 5e942d2..bb0f119 100644
--- a/tests/daemon/face/ethernet-factory.t.cpp
+++ b/tests/daemon/face/ethernet-factory.t.cpp
@@ -441,6 +441,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   SKIP_IF_ETHERNET_NETIF_COUNT_LT(1);
@@ -451,6 +452,7 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -458,6 +460,7 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -465,6 +468,15 @@
              localUri,
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("ether://[00:00:5e:00:53:57]"),
+             localUri,
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -475,6 +487,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
 
@@ -483,6 +496,7 @@
              FaceUri("udp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Creation of unicast Ethernet faces requires a LocalUri with dev:// scheme"});
 
@@ -491,6 +505,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing Ethernet faces do not support on-demand persistency"});
 
@@ -499,6 +514,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Cannot create multicast Ethernet faces"});
 
@@ -507,6 +523,7 @@
              FaceUri("dev://eth0"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
diff --git a/tests/daemon/face/factory-test-common.hpp b/tests/daemon/face/factory-test-common.hpp
index 046aeb2..83cf899 100644
--- a/tests/daemon/face/factory-test-common.hpp
+++ b/tests/daemon/face/factory-test-common.hpp
@@ -46,10 +46,11 @@
            const FaceUri& remoteUri,
            const ndn::optional<FaceUri>& localUri,
            ndn::nfd::FacePersistency persistency,
-           bool wantLocalFieldsEnabled,
+           bool wantLocalFields,
+           bool wantLpReliability,
            const CreateFaceExpectedResult& expected)
 {
-  factory.createFace({remoteUri, localUri, persistency, wantLocalFieldsEnabled},
+  factory.createFace({remoteUri, localUri, persistency, wantLocalFields, wantLpReliability},
                      [expected] (const shared_ptr<Face>&) {
                        BOOST_CHECK_EQUAL(CreateFaceExpectedResult::SUCCESS, expected.result);
                      },
diff --git a/tests/daemon/face/tcp-channel-fixture.hpp b/tests/daemon/face/tcp-channel-fixture.hpp
index 798fedd..a64cd48 100644
--- a/tests/daemon/face/tcp-channel-fixture.hpp
+++ b/tests/daemon/face/tcp-channel-fixture.hpp
@@ -1,5 +1,5 @@
 /* -*- 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,
@@ -50,7 +50,7 @@
   connect(TcpChannel& channel) final
   {
     g_io.post([&] {
-      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
+      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false,
         [this] (const shared_ptr<Face>& newFace) {
           BOOST_REQUIRE(newFace != nullptr);
           connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
diff --git a/tests/daemon/face/tcp-channel.t.cpp b/tests/daemon/face/tcp-channel.t.cpp
index d1a9626..3b5da41 100644
--- a/tests/daemon/face/tcp-channel.t.cpp
+++ b/tests/daemon/face/tcp-channel.t.cpp
@@ -47,7 +47,7 @@
 
   auto channel = this->makeChannel(typename IpAddressFromFamily<F::value>::type());
   channel->connect(tcp::Endpoint(address, 7040),
-    ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
+    ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false,
     [this] (const shared_ptr<nfd::Face>&) {
       BOOST_FAIL("Connect succeeded when it should have failed");
       this->limitedIo.afterOp();
diff --git a/tests/daemon/face/tcp-factory.t.cpp b/tests/daemon/face/tcp-factory.t.cpp
index f6307d6..c6fee2f 100644
--- a/tests/daemon/face/tcp-factory.t.cpp
+++ b/tests/daemon/face/tcp-factory.t.cpp
@@ -162,6 +162,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   factory.createChannel("127.0.0.1", "20071");
@@ -171,6 +172,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -178,6 +180,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -185,6 +188,15 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+  createFace(factory,
+             FaceUri("tcp4://127.0.0.1:20073"),
+             {},
+             ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -197,6 +209,7 @@
              FaceUri("tcp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Unicast TCP faces cannot be created with a LocalUri"});
 
@@ -205,6 +218,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing TCP faces do not support on-demand persistency"});
 
@@ -213,6 +227,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
@@ -247,7 +262,7 @@
   factory.createChannel("0.0.0.0", "20070");
 
   factory.createFace({FaceUri("tcp4://192.0.2.1:20070"), {},
-                      ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false},
+                      ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false, false},
                      bind(&CreateFaceTimeoutFixture::onFaceCreated, this, _1),
                      bind(&CreateFaceTimeoutFixture::onConnectFailed, this, _2));
 
diff --git a/tests/daemon/face/udp-channel-fixture.hpp b/tests/daemon/face/udp-channel-fixture.hpp
index ebb79fb..43f912d 100644
--- a/tests/daemon/face/udp-channel-fixture.hpp
+++ b/tests/daemon/face/udp-channel-fixture.hpp
@@ -1,5 +1,5 @@
 /* -*- 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,
@@ -51,7 +51,7 @@
   connect(UdpChannel& channel) final
   {
     g_io.post([&] {
-      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
+      channel.connect(listenerEp, ndn::nfd::FACE_PERSISTENCY_PERSISTENT, false,
         [this] (const shared_ptr<Face>& newFace) {
           BOOST_REQUIRE(newFace != nullptr);
           connectFaceClosedSignal(*newFace, [this] { limitedIo.afterOp(); });
diff --git a/tests/daemon/face/udp-factory.t.cpp b/tests/daemon/face/udp-factory.t.cpp
index 435b6d6..2747fa8 100644
--- a/tests/daemon/face/udp-factory.t.cpp
+++ b/tests/daemon/face/udp-factory.t.cpp
@@ -592,6 +592,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 504, "No channels available to connect"});
 
   factory.createChannel("127.0.0.1", "20071");
@@ -601,6 +602,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -608,6 +610,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 
   createFace(factory,
@@ -615,6 +618,16 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
+             {CreateFaceExpectedResult::SUCCESS, 0, ""});
+
+
+  createFace(factory,
+             FaceUri("udp4://127.0.0.1:20073"),
+             {},
+             ndn::nfd::FACE_PERSISTENCY_PERMANENT,
+             false,
+             true,
              {CreateFaceExpectedResult::SUCCESS, 0, ""});
 }
 
@@ -627,6 +640,7 @@
              FaceUri("udp4://127.0.0.1:20071"),
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Unicast UDP faces cannot be created with a LocalUri"});
 
@@ -635,6 +649,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Outgoing UDP faces do not support on-demand persistency"});
 
@@ -643,6 +658,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Cannot create multicast UDP faces"});
 
@@ -651,6 +667,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              true,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406,
               "Local fields can only be enabled on faces with local scope"});
 }
diff --git a/tests/daemon/face/unix-stream-factory.t.cpp b/tests/daemon/face/unix-stream-factory.t.cpp
index 76b1cb7..8d0e484 100644
--- a/tests/daemon/face/unix-stream-factory.t.cpp
+++ b/tests/daemon/face/unix-stream-factory.t.cpp
@@ -127,6 +127,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -134,6 +135,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -141,6 +143,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 }
 
diff --git a/tests/daemon/face/websocket-factory.t.cpp b/tests/daemon/face/websocket-factory.t.cpp
index 47b1a0f..380646e 100644
--- a/tests/daemon/face/websocket-factory.t.cpp
+++ b/tests/daemon/face/websocket-factory.t.cpp
@@ -188,6 +188,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERMANENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -195,6 +196,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_ON_DEMAND,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 
   createFace(factory,
@@ -202,6 +204,7 @@
              {},
              ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
              false,
+             false,
              {CreateFaceExpectedResult::FAILURE, 406, "Unsupported protocol"});
 }
 
diff --git a/tests/daemon/mgmt/face-manager-create-face.t.cpp b/tests/daemon/mgmt/face-manager-create-face.t.cpp
index 5a39ddb..19a10c7 100644
--- a/tests/daemon/mgmt/face-manager-create-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-create-face.t.cpp
@@ -159,6 +159,58 @@
   }
 };
 
+class TcpFaceLpReliabilityEnabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+  }
+};
+
+class TcpFaceLpReliabilityDisabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+  }
+};
+
+class UdpFaceLpReliabilityEnabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+  }
+};
+
+class UdpFaceLpReliabilityDisabled
+{
+public:
+  static ControlParameters
+  getParameters()
+  {
+    return ControlParameters()
+      .setUri("tcp4://127.0.0.1:26363")
+      .setFacePersistency(ndn::nfd::FACE_PERSISTENCY_PERSISTENT)
+      .setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+  }
+};
+
 class FaceUriMalformed
 {
 public:
@@ -206,6 +258,10 @@
                     mpl::pair<LocalTcpFaceLocalFieldsDisabled, CommandSuccess>,
                     mpl::pair<NonLocalUdpFaceLocalFieldsEnabled, CommandFailure<406>>,
                     mpl::pair<NonLocalUdpFaceLocalFieldsDisabled, CommandSuccess>,
+                    mpl::pair<TcpFaceLpReliabilityEnabled, CommandSuccess>,
+                    mpl::pair<TcpFaceLpReliabilityDisabled, CommandSuccess>,
+                    mpl::pair<UdpFaceLpReliabilityEnabled, CommandSuccess>,
+                    mpl::pair<UdpFaceLpReliabilityDisabled, CommandSuccess>,
                     mpl::pair<FaceUriMalformed, CommandFailure<400>>,
                     mpl::pair<FaceUriNonCanonical, CommandFailure<400>>,
                     mpl::pair<FaceUriUnsupportedScheme, CommandFailure<406>>>;
@@ -239,10 +295,13 @@
         if (expectedParams.hasFlags()) {
           BOOST_CHECK_EQUAL(expectedParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED),
                             actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED));
+          BOOST_CHECK_EQUAL(expectedParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED),
+                            actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
         }
         else {
           // local fields are disabled by default
           BOOST_CHECK_EQUAL(actualParams.getFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED), false);
+          BOOST_CHECK_EQUAL(actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED), false);
         }
       }
       else {
diff --git a/tests/daemon/mgmt/face-manager-update-face.t.cpp b/tests/daemon/mgmt/face-manager-update-face.t.cpp
index e81e3be..1d647fc 100644
--- a/tests/daemon/mgmt/face-manager-update-face.t.cpp
+++ b/tests/daemon/mgmt/face-manager-update-face.t.cpp
@@ -1,5 +1,5 @@
 /* -*- 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,
@@ -54,12 +54,14 @@
   void
   createFace(const std::string& uri = "tcp4://127.0.0.1:26363",
              ndn::nfd::FacePersistency persistency = ndn::nfd::FACE_PERSISTENCY_PERSISTENT,
-             bool enableLocalFields = false)
+             bool enableLocalFields = false,
+             bool enableReliability = false)
   {
     ControlParameters params;
     params.setUri(uri);
     params.setFacePersistency(persistency);
     params.setFlagBit(ndn::nfd::BIT_LOCAL_FIELDS_ENABLED, enableLocalFields);
+    params.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, enableReliability);
 
     createFace(params);
   }
@@ -548,6 +550,57 @@
   });
 }
 
+BOOST_AUTO_TEST_CASE(UpdateReliabilityEnableDisable)
+{
+  createFace("udp4://127.0.0.1:26363");
+
+  ControlParameters enableParams;
+  enableParams.setFaceId(faceId);
+  enableParams.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, true);
+
+  ControlParameters disableParams;
+  disableParams.setFaceId(faceId);
+  disableParams.setFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED, false);
+
+  updateFace(enableParams, false, [] (const ControlResponse& actual) {
+    ControlResponse expected(200, "OK");
+    BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
+    BOOST_TEST_MESSAGE(actual.getText());
+
+    if (actual.getBody().hasWire()) {
+      ControlParameters actualParams(actual.getBody());
+
+      BOOST_CHECK(actualParams.hasFaceId());
+      BOOST_CHECK(actualParams.hasFacePersistency());
+      BOOST_REQUIRE(actualParams.hasFlags());
+      // Check if flags indicate reliability enabled
+      BOOST_CHECK(actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
+    }
+    else {
+      BOOST_ERROR("Enable: Response does not contain ControlParameters");
+    }
+  });
+
+  updateFace(disableParams, false, [] (const ControlResponse& actual) {
+    ControlResponse expected(200, "OK");
+    BOOST_CHECK_EQUAL(actual.getCode(), expected.getCode());
+    BOOST_TEST_MESSAGE(actual.getText());
+
+    if (actual.getBody().hasWire()) {
+      ControlParameters actualParams(actual.getBody());
+
+      BOOST_CHECK(actualParams.hasFaceId());
+      BOOST_CHECK(actualParams.hasFacePersistency());
+      BOOST_REQUIRE(actualParams.hasFlags());
+      // Check if flags indicate reliability disabled
+      BOOST_CHECK(!actualParams.getFlagBit(ndn::nfd::BIT_LP_RELIABILITY_ENABLED));
+    }
+    else {
+      BOOST_ERROR("Disable: Response does not contain ControlParameters");
+    }
+  });
+}
+
 BOOST_AUTO_TEST_CASE(SelfUpdating)
 {
   createFace();