mgmt: make Uri and LocalUri required in faces/create success response

refs #3956

Change-Id: I62e924c12476aab0f7b7300ba8ff730ae72cbd73
diff --git a/tests/unit-tests/mgmt/nfd/control-command.t.cpp b/tests/unit-tests/mgmt/nfd/control-command.t.cpp
index ecabab2..72fe613 100644
--- a/tests/unit-tests/mgmt/nfd/control-command.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/control-command.t.cpp
@@ -31,66 +31,75 @@
 BOOST_AUTO_TEST_SUITE(Nfd)
 BOOST_AUTO_TEST_SUITE(TestControlCommand)
 
-BOOST_AUTO_TEST_CASE(FaceCreate)
+BOOST_AUTO_TEST_CASE(FaceCreateRequest)
 {
   FaceCreateCommand command;
 
+  // good with required fields only
   ControlParameters p1;
-  p1.setUri("tcp4://192.0.2.1")
-    .setFaceId(4);
-  BOOST_CHECK_THROW(command.validateRequest(p1), ControlCommand::ArgumentError);
-  BOOST_CHECK_THROW(command.validateResponse(p1), ControlCommand::ArgumentError);
+  p1.setUri("tcp4://192.0.2.1:6363");
+  BOOST_CHECK_NO_THROW(command.validateRequest(p1));
+  BOOST_CHECK(Name("/PREFIX/faces/create").isPrefixOf(command.getRequestName("/PREFIX", p1)));
 
-  ControlParameters p2;
-  p2.setName("ndn:/example");
-  BOOST_CHECK_THROW(command.validateRequest(p2), ControlCommand::ArgumentError);
-  BOOST_CHECK_THROW(command.validateResponse(p2), ControlCommand::ArgumentError);
-
-  ControlParameters p3;
-  p3.setUri("tcp4://192.0.2.1")
-    .setFaceId(INVALID_FACE_ID);
-  BOOST_CHECK_THROW(command.validateResponse(p3), ControlCommand::ArgumentError);
-
-  ControlParameters p4;
-  p4.setUri("tcp4://192.0.2.1")
-    .setLocalUri("dev://eth0")
-    .setFacePersistency(FACE_PERSISTENCY_PERSISTENT)
+  // good with optional fields
+  ControlParameters p2(p1);
+  p2.setLocalUri("tcp4://192.0.2.2:32114")
+    .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
     .setFlags(0x3)
     .setMask(0x1);
-  BOOST_CHECK_NO_THROW(command.validateRequest(p4));
+  BOOST_CHECK_NO_THROW(command.validateRequest(p1));
 
-  ControlParameters p5;
-  p5.setFaceId(27518)
+  // Uri is required
+  ControlParameters p3;
+  BOOST_CHECK_THROW(command.validateRequest(p3), ControlCommand::ArgumentError);
+
+  // Name is forbidden
+  ControlParameters p4(p1);
+  p4.setName("/example");
+  BOOST_CHECK_THROW(command.validateRequest(p4), ControlCommand::ArgumentError);
+
+  // Flags and Mask must be specified together
+  ControlParameters p5(p1);
+  p5.setFlags(0x3);
+  BOOST_CHECK_THROW(command.validateRequest(p5), ControlCommand::ArgumentError);
+
+  ControlParameters p6(p1);
+  p6.setMask(0x1);
+  BOOST_CHECK_THROW(command.validateRequest(p6), ControlCommand::ArgumentError);
+}
+
+BOOST_AUTO_TEST_CASE(FaceCreateResponse)
+{
+  FaceCreateCommand command;
+
+  // good
+  ControlParameters p1;
+  p1.setFaceId(3208)
     .setUri("tcp4://192.0.2.1:6363")
     .setLocalUri("tcp4://192.0.2.2:32114")
     .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
-    .setFlags(0x1);
-  BOOST_CHECK_THROW(command.validateRequest(p5), ControlCommand::ArgumentError);
-  BOOST_CHECK_NO_THROW(command.validateResponse(p5));
+    .setFlags(0x3);
+  BOOST_CHECK_NO_THROW(command.validateResponse(p1));
 
-  p4.unsetFacePersistency();
-  BOOST_CHECK_NO_THROW(command.validateRequest(p4));
-  command.applyDefaultsToRequest(p4);
-  BOOST_REQUIRE(p4.hasFacePersistency());
-  BOOST_CHECK_EQUAL(p4.getFacePersistency(), FACE_PERSISTENCY_PERSISTENT);
+  // Name is forbidden
+  ControlParameters p2(p1);
+  p2.setName("/example");
+  BOOST_CHECK_THROW(command.validateResponse(p2), ControlCommand::ArgumentError);
 
-  ControlParameters p6;
-  p6.setFaceId(4)
-    .setUri("tcp4://192.0.2.1")
-    .setFacePersistency(FACE_PERSISTENCY_PERSISTENT);
-  BOOST_CHECK_NO_THROW(command.validateResponse(p6));
+  // Mask is forbidden
+  ControlParameters p3(p1);
+  p3.setMask(0x1);
+  BOOST_CHECK_THROW(command.validateResponse(p3), ControlCommand::ArgumentError);
 
-  ControlParameters p7;
-  p7.setUri("tcp4://192.0.2.1:6363");
-  Name n7;
-  BOOST_CHECK_NO_THROW(n7 = command.getRequestName("/PREFIX", p7));
-  BOOST_CHECK(Name("ndn:/PREFIX/faces/create").isPrefixOf(n7));
+  // FaceId must be valid
+  ControlParameters p4(p1);
+  p4.setFaceId(INVALID_FACE_ID);
+  BOOST_CHECK_THROW(command.validateResponse(p4), ControlCommand::ArgumentError);
 
-  ControlParameters p8;
-  p8.setFaceId(5)
-    .setFacePersistency(FACE_PERSISTENCY_PERMANENT)
-    .setFlags(0x2);
-  BOOST_CHECK_NO_THROW(command.validateResponse(p8));
+  // LocalUri is required
+  ControlParameters p5(p1);
+  p5.unsetLocalUri();
+  BOOST_CHECK_THROW(command.validateResponse(p5), ControlCommand::ArgumentError);
 }
 
 BOOST_AUTO_TEST_CASE(FaceUpdate)
diff --git a/tests/unit-tests/mgmt/nfd/controller.t.cpp b/tests/unit-tests/mgmt/nfd/controller.t.cpp
index 4d6b8a2..423499a 100644
--- a/tests/unit-tests/mgmt/nfd/controller.t.cpp
+++ b/tests/unit-tests/mgmt/nfd/controller.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2016 Regents of the University of California.
+ * Copyright (c) 2013-2017 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -44,6 +44,15 @@
   {
   }
 
+  void
+  respond(const ControlResponse& responsePayload)
+  {
+    auto responseData = makeData(face.sentInterests.at(0).getName());
+    responseData->setContent(responsePayload.wireEncode());
+    face.receive(*responseData);
+    this->advanceClocks(time::milliseconds(1));
+  }
+
 private:
   void
   succeed(const ControlParameters& parameters)
@@ -61,13 +70,24 @@
 // StatusDataset functionality is tested in nfd-status-dataset.t.cpp
 BOOST_FIXTURE_TEST_SUITE(TestController, CommandFixture)
 
+static ControlParameters
+makeFaceCreateResponse()
+{
+  ControlParameters resp;
+  resp.setFaceId(22)
+      .setUri("tcp4://192.0.2.1:6363")
+      .setLocalUri("tcp4://192.0.2.2:10847")
+      .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT)
+      .setFlags(0x7);
+  return resp;
+}
+
 BOOST_AUTO_TEST_CASE(Success)
 {
   ControlParameters parameters;
   parameters.setUri("tcp4://192.0.2.1:6363");
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback));
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
@@ -84,18 +104,10 @@
   BOOST_CHECK_EQUAL(request.getUri(), parameters.getUri());
   BOOST_CHECK_EQUAL(requestInterest.getInterestLifetime(), CommandOptions::DEFAULT_TIMEOUT);
 
-  ControlParameters responseBody;
-  responseBody.setUri("tcp4://192.0.2.1:6363")
-              .setFaceId(22)
-              .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
+  ControlParameters responseBody = makeFaceCreateResponse();
   ControlResponse responsePayload(201, "created");
   responsePayload.setBody(responseBody.wireEncode());
-
-  auto responseData = makeData(requestInterest.getName());
-  responseData->setContent(responsePayload.wireEncode());
-  face.receive(*responseData);
-
-  this->advanceClocks(time::milliseconds(1));
+  this->respond(responsePayload);
 
   BOOST_CHECK_EQUAL(failCodes.size(), 0);
   BOOST_REQUIRE_EQUAL(succeeds.size(), 1);
@@ -111,21 +123,10 @@
   controller.start<FaceCreateCommand>(parameters, nullptr, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
-  const Interest& requestInterest = face.sentInterests[0];
-
-  ControlParameters responseBody;
-  responseBody.setUri("tcp4://192.0.2.1:6363")
-              .setFaceId(22)
-              .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
+  ControlParameters responseBody = makeFaceCreateResponse();
   ControlResponse responsePayload(201, "created");
   responsePayload.setBody(responseBody.wireEncode());
-
-  auto responseData = makeData(requestInterest.getName());
-  responseData->setContent(responsePayload.wireEncode());
-  face.receive(*responseData);
-
-  BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(1)));
+  this->respond(responsePayload);
 
   BOOST_CHECK_EQUAL(failCodes.size(), 0);
 }
@@ -139,16 +140,14 @@
   CommandOptions options;
   options.setPrefix("/localhop/net/example/router1/nfd");
 
-  BOOST_CHECK_NO_THROW(controller.start<RibRegisterCommand>(
-                         parameters, succeedCallback, commandFailCallback, options));
+  controller.start<RibRegisterCommand>(parameters, succeedCallback, commandFailCallback, options);
   this->advanceClocks(time::milliseconds(1));
 
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
   const Interest& requestInterest = face.sentInterests[0];
 
   FaceCreateCommand command;
-  BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(
-              requestInterest.getName()));
+  BOOST_CHECK(Name("/localhop/net/example/router1/nfd/rib/register").isPrefixOf(requestInterest.getName()));
 }
 
 BOOST_AUTO_TEST_CASE(InvalidRequest)
@@ -169,24 +168,13 @@
   ControlParameters parameters;
   parameters.setUri("tcp4://192.0.2.1:6363");
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback));
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
-  const Interest& requestInterest = face.sentInterests[0];
-
-  ControlParameters responseBody;
-  responseBody.setUri("tcp4://192.0.2.1:6363")
-              .setFaceId(22)
-              .setFacePersistency(ndn::nfd::FacePersistency::FACE_PERSISTENCY_PERSISTENT);
+  ControlParameters responseBody = makeFaceCreateResponse();
   ControlResponse responsePayload(201, "created");
   responsePayload.setBody(responseBody.wireEncode());
-
-  auto responseData = makeData(requestInterest.getName());
-  responseData->setContent(responsePayload.wireEncode());
-  face.receive(*responseData);
-  this->advanceClocks(time::milliseconds(1));
+  this->respond(responsePayload);
 
   BOOST_CHECK_EQUAL(succeeds.size(), 0);
   BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
@@ -198,19 +186,11 @@
   ControlParameters parameters;
   parameters.setUri("tcp4://192.0.2.1:6363");
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback));
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
-  const Interest& requestInterest = face.sentInterests[0];
-
   ControlResponse responsePayload(401, "Not Authenticated");
-
-  auto responseData = makeData(requestInterest.getName());
-  responseData->setContent(responsePayload.wireEncode());
-  face.receive(*responseData);
-  this->advanceClocks(time::milliseconds(1));
+  this->respond(responsePayload);
 
   BOOST_CHECK_EQUAL(succeeds.size(), 0);
   BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
@@ -222,24 +202,15 @@
   ControlParameters parameters;
   parameters.setUri("tcp4://192.0.2.1:6363");
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback));
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
-  BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
-  const Interest& requestInterest = face.sentInterests[0];
-
-  ControlParameters responseBody;
-  responseBody.setUri("tcp4://192.0.2.1:6363")
+  ControlParameters responseBody = makeFaceCreateResponse();
+  responseBody.unsetFaceId() // FaceId is missing
               .setName("ndn:/should-not-have-this-field");
-  // FaceId is missing
   ControlResponse responsePayload(201, "created");
   responsePayload.setBody(responseBody.wireEncode());
-
-  auto responseData = makeData(requestInterest.getName());
-  responseData->setContent(responsePayload.wireEncode());
-  face.receive(*responseData);
-  this->advanceClocks(time::milliseconds(1));
+  this->respond(responsePayload);
 
   BOOST_CHECK_EQUAL(succeeds.size(), 0);
   BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
@@ -250,8 +221,7 @@
   ControlParameters parameters;
   parameters.setUri("tcp4://192.0.2.1:6363");
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback));
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback);
   this->advanceClocks(time::milliseconds(1));
 
   BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
@@ -273,9 +243,9 @@
   CommandOptions options;
   options.setTimeout(time::milliseconds(50));
 
-  BOOST_CHECK_NO_THROW(controller.start<FaceCreateCommand>(
-                         parameters, succeedCallback, commandFailCallback, options));
-  this->advanceClocks(time::milliseconds(1), 101); // Face's PIT granularity is 100ms
+  controller.start<FaceCreateCommand>(parameters, succeedCallback, commandFailCallback, options);
+  this->advanceClocks(time::milliseconds(1)); // express Interest
+  this->advanceClocks(time::milliseconds(51)); // timeout
 
   BOOST_REQUIRE_EQUAL(failCodes.size(), 1);
   BOOST_CHECK_EQUAL(failCodes.back(), Controller::ERROR_TIMEOUT);
@@ -290,8 +260,8 @@
   options.setTimeout(time::milliseconds(50));
 
   controller.start<FaceCreateCommand>(parameters, succeedCallback, nullptr, options);
-  BOOST_CHECK_NO_THROW(this->advanceClocks(time::milliseconds(100), 10));
-  // timeout
+  this->advanceClocks(time::milliseconds(1)); // express Interest
+  this->advanceClocks(time::milliseconds(51)); // timeout
 
   BOOST_CHECK_EQUAL(succeeds.size(), 0);
 }