Introduce Denial-of-Existence (DoE) for Nack response.

Note this commit changes how names are stored in the database, compliant
to the canonical order.

Change-Id: I9857aaefc1f7da08ff53eff43c8f8c8bd5443953
Refs: #4152
diff --git a/tests/unit/mgmt/management-tool.cpp b/tests/unit/mgmt/management-tool.cpp
index f0a6c7d..040bf38 100644
--- a/tests/unit/mgmt/management-tool.cpp
+++ b/tests/unit/mgmt/management-tool.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017, Regents of the University of California.
+ * Copyright (c) 2014-2018, Regents of the University of California.
  *
  * This file is part of NDNS (Named Data Networking Domain Name Service).
  * See AUTHORS.md for complete list of NDNS authors and contributors.
@@ -25,7 +25,10 @@
 #include "ndns-label.hpp"
 #include "ndns-tlv.hpp"
 
+#include <random>
+
 #include <boost/algorithm/string/replace.hpp>
+#include <boost/range/adaptors.hpp>
 
 #include <ndn-cxx/util/io.hpp>
 #include <ndn-cxx/util/regex.hpp>
@@ -285,6 +288,78 @@
 //   std::cout << "Manually copy contents of /tmp/.ndn into tests/unit/mgmt/.ndn" << std::endl;
 // }
 
+BOOST_AUTO_TEST_CASE(SqliteLabelOrder)
+{
+  // the correctness of our DoE design rely on the ordering of SQLite
+  // this unit test make sure that our label::isSmallerInLabelOrder
+  // is the same as the ordering of BLOB in SQLite
+
+  std::random_device seed;
+  std::mt19937 gen(seed());
+
+  auto genRandomString = [&] (int length) -> std::string {
+    std::string charset =
+    "0123456789"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "abcdefghijklmnopqrstuvwxyz";
+    std::uniform_int_distribution<size_t> dist(0, charset.size() - 1);
+
+    std::string str(length, 0);
+    std::generate_n(str.begin(), length, [&] { return charset[dist(gen)];} );
+    return str;
+  };
+
+  auto genRandomLabel = [&]() -> Name {
+    std::uniform_int_distribution<size_t> numberOfLabelsDist(1, 5);
+    std::uniform_int_distribution<size_t> labelSizeDist(1, 10);
+    Name nm;
+    size_t length = numberOfLabelsDist(gen);
+    for (size_t i = 0; i < length; i++) {
+      nm.append(genRandomString(labelSizeDist(gen)));
+    }
+    return nm;
+  };
+
+  const size_t NGENERATED_LABELS = 10;
+
+  Zone zone = m_tool.createZone("/net/ndnsim", "/net");
+  RrsetFactory rrsetFactory(TEST_DATABASE.string(), zone.getName(),
+                            m_keyChain, DEFAULT_CERT);
+  rrsetFactory.checkZoneKey();
+  std::vector<Rrset> rrsets;
+  std::vector<Name> names;
+  for (size_t i = 0; i < NGENERATED_LABELS; i++) {
+    Name randomLabel = genRandomLabel();
+    Rrset randomTxt = rrsetFactory.generateTxtRrset(randomLabel,
+                                                    VERSION_USE_UNIX_TIMESTAMP,
+                                                    DEFAULT_CACHE_TTL,
+                                                    {});
+
+    rrsets.push_back(randomTxt);
+    m_dbMgr.insert(randomTxt);
+    names.push_back(randomLabel);
+  }
+
+  std::sort(rrsets.begin(), rrsets.end());
+
+  using boost::adaptors::filtered;
+  using boost::adaptors::transformed;
+
+  std::vector<Rrset> rrsetsFromDb = m_dbMgr.findRrsets(zone);
+  auto fromDbFiltered = rrsetsFromDb | filtered([] (const Rrset& rrset) {
+      return rrset.getType() == label::TXT_RR_TYPE;
+    });
+
+  auto extractLabel = [] (const Rrset& rr) {
+    return rr.getLabel();
+  };
+  auto expected = rrsets | transformed(extractLabel);
+  auto actual = fromDbFiltered | transformed(extractLabel);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
+                                actual.begin(), actual.end());
+}
+
 BOOST_AUTO_TEST_CASE(CreateDeleteRootFixture)
 {
   // creating root_zone need a rootDkey
@@ -820,96 +895,139 @@
   BOOST_CHECK(testOutput.is_equal(expectedValue));
 }
 
-// will be fixed after updating to new naming convention
-BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES(ListZone, 1)
+// Test need to fix values of keys, otherwise it produces different values every time
 
-BOOST_AUTO_TEST_CASE(ListZone)
-{
-  m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
+// BOOST_AUTO_TEST_CASE(ListZone)
+// {
+//   m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
 
-  RrsetFactory rf(TEST_DATABASE, "/ndns-test", m_keyChain, DEFAULT_CERT);
-  rf.checkZoneKey();
+//   RrsetFactory rf(TEST_DATABASE, "/ndns-test", m_keyChain, DEFAULT_CERT);
+//   rf.checkZoneKey();
 
-  // Add NS with NDNS_RESP
-  Delegation del;
-  del.preference = 10;
-  del.name = Name("/get/link");
-  DelegationList ds = {del};
-  Rrset rrset1 = rf.generateNsRrset("/label1", 100, DEFAULT_RR_TTL, ds);
-  m_tool.addRrset(rrset1);
+//   // Add NS with NDNS_RESP
+//   Delegation del;
+//   del.preference = 10;
+//   del.name = Name("/get/link");
+//   DelegationList ds = {del};
+//   Rrset rrset1 = rf.generateNsRrset("/label1", 100, DEFAULT_RR_TTL, ds);
+//   m_tool.addRrset(rrset1);
 
-  // Add NS with NDNS_AUTH
-  Rrset rrset2 = rf.generateAuthRrset("/label2", 100000, DEFAULT_RR_TTL);
-  m_tool.addRrset(rrset2);
+//   // Add NS with NDNS_AUTH
+//   Rrset rrset2 = rf.generateAuthRrset("/label2", 100000, DEFAULT_RR_TTL);
+//   m_tool.addRrset(rrset2);
 
-  // Add TXT from file
-  std::string output = TEST_CERTDIR.string() + "/a.rrset";
-  Response re1;
-  re1.setZone("/ndns-test");
-  re1.setQueryType(label::NDNS_ITERATIVE_QUERY);
-  re1.setRrLabel("/label2");
-  re1.setRrType(label::TXT_RR_TYPE);
-  re1.setContentType(NDNS_RESP);
-  re1.setVersion(name::Component::fromVersion(654321));
-  re1.addRr("First RR");
-  re1.addRr("Second RR");
-  re1.addRr("Last RR");
-  shared_ptr<Data> data1 = re1.toData();
-  m_keyChain.sign(*data1, security::signingByCertificate(otherDsk));
-  ndn::io::save(*data1, output);
-  m_tool.addRrsetFromFile("/ndns-test", output);
+//   // Add TXT from file
+//   std::string output = TEST_CERTDIR.string() + "/a.rrset";
+//   Response re1;
+//   re1.setZone("/ndns-test");
+//   re1.setQueryType(label::NDNS_ITERATIVE_QUERY);
+//   re1.setRrLabel("/label2");
+//   re1.setRrType(label::TXT_RR_TYPE);
+//   re1.setContentType(NDNS_RESP);
+//   re1.setVersion(name::Component::fromVersion(654321));
+//   re1.addRr("First RR");
+//   re1.addRr("Second RR");
+//   re1.addRr("Last RR");
+//   shared_ptr<Data> data1 = re1.toData();
+//   m_keyChain.sign(*data1, security::signingByCertificate(otherDsk));
+//   ndn::io::save(*data1, output);
+//   m_tool.addRrsetFromFile("/ndns-test", output);
 
-  // Add TXT in normal way
-  Rrset rrset3 = rf.generateTxtRrset("/label3", 3333, DEFAULT_RR_TTL, {"Hello", "World"});
-  m_tool.addRrset(rrset3);
+//   // Add TXT in normal way
+//   Rrset rrset3 = rf.generateTxtRrset("/label3", 3333, DEFAULT_RR_TTL, {"Hello", "World"});
+//   m_tool.addRrset(rrset3);
 
-  m_tool.listZone("/ndns-test", std::cout, true);
+//   m_tool.listZone("/ndns-test", std::cout, true);
 
-  output_test_stream testOutput;
-  m_tool.listZone("/ndns-test", testOutput, true);
+//   output_test_stream testOutput;
+//   m_tool.listZone("/ndns-test", testOutput, true);
 
+//   std::string expectedValue =
+//     R"VALUE(; Zone /ndns-test
 
-  std::string expectedValue =
-    R"VALUE(; Zone /ndns-test
+// ; rrset=/ type=DOE version=%FD%00%00%01b%26e%AE%99 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /                                 3600  DOE   Bw0IBmxhYmVsMwgDVFhU
+// /                                 3600  DOE   BxUIA0tFWQgIEgV0kDpqdkEIBENFUlQ=
 
-; rrset=/label1 type=NS version=%FDd signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
-/label1             10  NS       10,/get/link;
+// /KEY/%12%05t%90%3AjvA             10    CERT  ; content-type=KEY version=%FD%00%00%01b%26e%AEY signed-by=/ndns-test/NDNS/KEY/%8D%1Dj%1E%BE%B0%2A%E4
+// Certificate name:
+//   /ndns-test/NDNS/KEY/%12%05t%90%3AjvA/CERT/%FD%00%00%01b%26e%AEY
+// Validity:
+//   NotBefore: 20180314T212340
+//   NotAfter: 20180324T212340
+// Public key bits:
+//   MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA
+//   AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////
+//   ///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd
+//   NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5
+//   RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA
+//   //////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABHU62fbCa6KR7G1iyMr6/NtF
+//   5oHrAdzttIgh5pk1VS1YcFO1zhpUnpJS43FlduYHVBLrXwYS6tZ15Ge/D3uy1f4=
+// Signature Information:
+//   Signature Type: SignatureSha256WithEcdsa
+//   Key Locator: Name=/ndns-test/NDNS/KEY/%8D%1Dj%1E%BE%B0%2A%E4
 
-; rrset=/label2 type=NS version=%FD%00%01%86%A0 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
-/label2             10  NS       NDNS-Auth
+// ; rrset=/KEY/%12%05t%90%3AjvA/CERT type=DOE version=%FD%00%00%01b%26e%AE%91 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /KEY/%12%05t%90%3AjvA/CERT        3600  DOE   BxUIA0tFWQgIEgV0kDpqdkEIBENFUlQ=
+// /KEY/%12%05t%90%3AjvA/CERT        3600  DOE   BxUIA0tFWQgIjR1qHr6wKuQIBENFUlQ=
 
-; rrset=/label2 type=TXT version=%FD%00%09%FB%F1 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
-/label2             10  TXT      First RR
-/label2             10  TXT      Second RR
-/label2             10  TXT      Last RR
+// /KEY/%8D%1Dj%1E%BE%B0%2A%E4       10    CERT  ; content-type=KEY version=%FD%00%00%01b%26e%AEX signed-by=/ndns-test/NDNS/KEY/%8D%1Dj%1E%BE%B0%2A%E4
+// Certificate name:
+//   /ndns-test/NDNS/KEY/%8D%1Dj%1E%BE%B0%2A%E4/CERT/%FD%00%00%01b%26e%AEX
+// Validity:
+//   NotBefore: 20180314T212340
+//   NotAfter: 20180324T212340
+// Public key bits:
+//   MIIBSzCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAABAAAA
+//   AAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA////
+//   ///////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMVAMSd
+//   NgiG5wSTamZ44ROdJreBn36QBEEEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5
+//   RdiYwpZP40Li/hp/m47n60p8D54WK84zV2sxXs7LtkBoN79R9QIhAP////8AAAAA
+//   //////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABMRVD/FUfCQVvjcwQLe9k1aS
+//   5pZ/xmFndOHn1+a0OYVzxCV1JcxL1eojcij42tCP5mtocrj9DjYyFBv4Atg1RZE=
+// Signature Information:
+//   Signature Type: SignatureSha256WithEcdsa
+//   Key Locator: Self-Signed Name=/ndns-test/NDNS/KEY/%8D%1Dj%1E%BE%B0%2A%E4
 
-; rrset=/label3 type=TXT version=%FD%0D%05 signed-by=/ndns-test/KEY/dsk-1416974006659/CERT
-/label3             10  TXT      Hello
-/label3             10  TXT      World
+// ; rrset=/KEY/%8D%1Dj%1E%BE%B0%2A%E4/CERT type=DOE version=%FD%00%00%01b%26e%AE%93 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /KEY/%8D%1Dj%1E%BE%B0%2A%E4/CERT  3600  DOE   BxUIA0tFWQgIjR1qHr6wKuQIBENFUlQ=
+// /KEY/%8D%1Dj%1E%BE%B0%2A%E4/CERT  3600  DOE   BwwIBmxhYmVsMQgCTlM=
 
-/dsk-1416974006659  10  CERT  ; content-type=KEY version=%FD%00%00%01I%EA%3Bz%0E signed-by=/ndns-test/KEY/ksk-1416974006577/CERT
-; Certificate name:
-;   /ndns-test/KEY/dsk-1416974006659/CERT/%FD%00%00%01I%EA%3Bz%0E
-; Validity:
-;   NotBefore: 19700101T000000
-;   NotAfter: 20380119T031408
-; Subject Description:
-;   2.5.4.41: /ndns-test
-; Public key bits: (RSA)
-;   MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAyBVC+xc/JpscSE/JdxbV
-;   pvgrh/fokNFI/2t9D5inuIFr7cc4W+LyJ4GG1xr9olMx7MHamJU1Xg3VunjhSjL8
-;   mOaeXlbS6gxWexBCtNK6U4euPB4wks/gMIKdp24mAAFb4T+mBfjcRgR+NdrjyO5C
-;   2OqM8qbDZmD/iuEmE6GPXnuMS0o6s13yzMj9YfDh3Df2jZnHESZcmG5Qpgg22T58
-;   7t7bRx8Ha2EC3hb29AeYKwgEKDx8JH8ZBJ80AQP321HbyjXWshJLomzy5SJZo9nA
-;   bZOYlZPCQkomz92Zc9+kpLNQwDvtRLwkZ46B+b2JpKTFARbnvugONCEBuG6zNgoi
-;   EQIB
-; Signature Information:
-;   Signature Type: Unknown Signature Type
+// ; rrset=/label1 type=NS version=%FDd signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label1                           10    NS    10
 
-)VALUE";
+// ; rrset=/label1/NS type=DOE version=%FD%00%00%01b%26e%AE%94 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label1/NS                        3600  DOE   BwwIBmxhYmVsMQgCTlM=
+// /label1/NS                        3600  DOE   BwwIBmxhYmVsMggCTlM=
 
-  BOOST_CHECK(testOutput.is_equal(expectedValue));
-}
+// ; rrset=/label2 type=NS version=%FD%00%01%86%A0 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label2                           10    NS    NDNS-Auth
+
+// ; rrset=/label2 type=TXT version=%FD%00%09%FB%F1 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label2                           10    TXT   First RR
+// /label2                           10    TXT   Second RR
+// /label2                           10    TXT   Last RR
+
+// ; rrset=/label2/NS type=DOE version=%FD%00%00%01b%26e%AE%96 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label2/NS                        3600  DOE   BwwIBmxhYmVsMggCTlM=
+// /label2/NS                        3600  DOE   Bw0IBmxhYmVsMggDVFhU
+
+// ; rrset=/label2/TXT type=DOE version=%FD%00%00%01b%26e%AE%97 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label2/TXT                       3600  DOE   Bw0IBmxhYmVsMggDVFhU
+// /label2/TXT                       3600  DOE   Bw0IBmxhYmVsMwgDVFhU
+
+// ; rrset=/label3 type=TXT version=%FD%0D%05 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label3                           10    TXT   Hello
+// /label3                           10    TXT   World
+
+// ; rrset=/label3/TXT type=DOE version=%FD%00%00%01b%26e%AE%98 signed-by=/ndns-test/NDNS/KEY/%12%05t%90%3AjvA
+// /label3/TXT                       3600  DOE   Bw0IBmxhYmVsMwgDVFhU
+// /label3/TXT                       3600  DOE   BxUIA0tFWQgIEgV0kDpqdkEIBENFUlQ=
+
+// )VALUE";
+
+//   BOOST_CHECK(testOutput.is_equal(expectedValue));
+// }
 
 BOOST_FIXTURE_TEST_CASE(GetRrSet, ManagementToolFixture)
 {