security: Add option to disable infrastructure interest in CertificateFetcherDirectFetch

Refs: #4879
Change-Id: I4ee7f831fde1fe6e951857c279546f7b7433def0
diff --git a/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp b/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
index e2d543c..7e513c6 100644
--- a/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
+++ b/tests/unit/security/v2/certificate-fetcher-direct-fetch.t.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2013-2018 Regents of the University of California.
+ * Copyright (c) 2013-2019 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -58,6 +58,13 @@
                                                                                  CertificateFetcherDirectFetch>
 {
 public:
+  enum class ResponseType {
+    INFRASTRUCTURE,
+    DIRECT,
+    BOTH
+  };
+
+public:
   CertificateFetcherDirectFetchFixture()
     : data("/Security/V2/ValidatorFixture/Sub1/Sub3/Data")
     , interest("/Security/V2/ValidatorFixture/Sub1/Sub3/Interest")
@@ -76,7 +83,14 @@
     processInterest = [this] (const Interest& interest) {
       auto nextHopFaceIdTag = interest.template getTag<lp::NextHopFaceIdTag>();
       if (nextHopFaceIdTag == nullptr) {
-        makeResponse(interest); // respond only to the "infrastructure" interest
+        if (responseType == ResponseType::INFRASTRUCTURE || responseType == ResponseType::BOTH) {
+          makeResponse(interest);
+        }
+      }
+      else {
+        if (responseType == ResponseType::DIRECT || responseType == ResponseType::BOTH) {
+          makeResponse(interest);
+        }
       }
     };
   }
@@ -84,10 +98,17 @@
   void
   makeResponse(const Interest& interest);
 
+  void
+  setResponseType(ResponseType type)
+  {
+    responseType = type;
+  }
+
 public:
   Data data;
   Interest interest;
   Interest interestNoTag;
+  ResponseType responseType = ResponseType::INFRASTRUCTURE;
 };
 
 template<>
@@ -137,11 +158,24 @@
   }
 }
 
+BOOST_FIXTURE_TEST_CASE(ValidateSuccessDataDirectOnly, CertificateFetcherDirectFetchFixture<Cert>)
+{
+  setResponseType(ResponseType::DIRECT);
+  static_cast<CertificateFetcherDirectFetch&>(validator.getFetcher()).setSendDirectInterestOnly(true);
+
+  VALIDATE_SUCCESS(this->data, "Should get accepted, direct interests bring certs");
+  BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 2);
+
+  for (const auto& sentInterest : this->face.sentInterests) {
+    BOOST_CHECK(sentInterest.template getTag<lp::NextHopFaceIdTag>() != nullptr);
+  }
+}
+
 BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureData, T, Failures, CertificateFetcherDirectFetchFixture<T>)
 {
   VALIDATE_FAILURE(this->data, "Should fail, as all interests either NACKed or timeout");
   // Direct fetcher sends two interests each time - to network and face
-  // 3 retries on nack or timeout (2 * (1 + 3) = 4)
+  // 3 retries on nack or timeout (2 * (1 + 3) = 8)
   BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 8);
 
   // odd interests
@@ -157,6 +191,34 @@
   }
 }
 
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureDataDirectOnly, T, Failures, CertificateFetcherDirectFetchFixture<T>)
+{
+  this->setResponseType(CertificateFetcherDirectFetchFixture<T>::ResponseType::DIRECT);
+  static_cast<CertificateFetcherDirectFetch&>(this->validator.getFetcher()).setSendDirectInterestOnly(true);
+
+  VALIDATE_FAILURE(this->data, "Should fail, as all interests either NACKed or timeout");
+  // Direct fetcher sends two interests each time - to network and face
+  // 3 retries on nack or timeout (1 + 3 = 4)
+  BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 4);
+
+  for (const auto& sentInterest : this->face.sentInterests) {
+    BOOST_CHECK(sentInterest.template getTag<lp::NextHopFaceIdTag>() != nullptr);
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(ValidateFailureDataNoTagDirectOnly, T, Failures, CertificateFetcherDirectFetchFixture<T>)
+{
+  this->setResponseType(CertificateFetcherDirectFetchFixture<T>::ResponseType::DIRECT);
+  static_cast<CertificateFetcherDirectFetch&>(this->validator.getFetcher()).setSendDirectInterestOnly(true);
+
+  this->data.template removeTag<lp::IncomingFaceIdTag>();
+  this->interest.template removeTag<lp::IncomingFaceIdTag>();
+
+  VALIDATE_FAILURE(this->data, "Should fail, as no interests are expected");
+  BOOST_CHECK_EQUAL(this->face.sentInterests.size(), 0);
+  BOOST_CHECK(this->lastError.getCode() != ValidationError::Code::IMPLEMENTATION_ERROR);
+}
+
 BOOST_FIXTURE_TEST_CASE(ValidateSuccessInterest, CertificateFetcherDirectFetchFixture<Cert>)
 {
   VALIDATE_SUCCESS(this->interest, "Should get accepted, normal and/or direct interests bring certs");