Add MetadataObject class to encode/decode RDR-style metadata
Change-Id: I6688b630a4889614e7df5c1f91b91be370a350cd
Refs: #4707
diff --git a/tests/unit/metadata-object.t.cpp b/tests/unit/metadata-object.t.cpp
new file mode 100644
index 0000000..6074c59
--- /dev/null
+++ b/tests/unit/metadata-object.t.cpp
@@ -0,0 +1,152 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2013-2019 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * @author Chavoosh Ghasemi <chghasemi@cs.arizona.edu>
+ */
+
+#include "ndn-cxx/metadata-object.hpp"
+
+#include "tests/boost-test.hpp"
+#include "tests/identity-management-fixture.hpp"
+
+namespace ndn {
+namespace tests {
+
+class MetadataObjectFixture : public IdentityManagementFixture
+{
+public:
+ MetadataObjectFixture()
+ : metadataComponent(32, reinterpret_cast<const uint8_t*>("metadata"), std::strlen("metadata"))
+ , versionedContentName(Name(baseContentName)
+ .appendVersion(342092199154ULL))
+ , metadataFullName(Name(baseContentName)
+ .append(metadataComponent)
+ .appendVersion(metadataVerNo)
+ .appendSegment(0))
+ {
+ }
+
+protected:
+ const name::Component metadataComponent;
+
+ // content prefix
+ const Name baseContentName = "/ndn/unit/tests";
+ const Name versionedContentName;
+
+ // metadata prefix
+ const uint64_t metadataVerNo = 89400192181ULL;
+ const Name metadataFullName;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestMetadataObject, MetadataObjectFixture)
+
+BOOST_AUTO_TEST_CASE(EncodeDecode)
+{
+ MetadataObject metadata1;
+ metadata1.setVersionedName(versionedContentName);
+
+ // pass metadata version number
+ const Data data1 = metadata1.makeData(metadataFullName.getPrefix(-2), m_keyChain,
+ KeyChain::getDefaultSigningInfo(), metadataVerNo);
+
+ BOOST_CHECK_EQUAL(metadata1.getVersionedName(), versionedContentName);
+ BOOST_CHECK_EQUAL(data1.getName(), metadataFullName);
+ BOOST_CHECK_EQUAL(data1.getFreshnessPeriod(), 10_ms);
+
+ // do not pass metadata version number
+ metadata1.setVersionedName(versionedContentName);
+ const Data data2 = metadata1.makeData(metadataFullName.getPrefix(-2), m_keyChain);
+ BOOST_CHECK_NE(data2.getName()[-2].toVersion(), metadataVerNo);
+
+ // construct a metadata object based on a valid metadata packet
+ MetadataObject metadata2(data1);
+
+ BOOST_CHECK_EQUAL(metadata2.getVersionedName(), versionedContentName);
+ BOOST_CHECK(baseContentName.isPrefixOf(metadata2.makeData(metadataFullName.getPrefix(-2),
+ m_keyChain).getName()));
+}
+
+BOOST_AUTO_TEST_CASE(InvalidFormat)
+{
+ Data data;
+
+ // invalid content type
+ data.setName(Name("/ndn/unit/test").append(metadataComponent));
+ data.setContentType(tlv::ContentType_Key);
+ BOOST_CHECK_THROW(MetadataObject metadata(data), tlv::Error);
+
+ // invalid metadata name
+ data.setName("/ndn/unit/test");
+ data.setContentType(tlv::ContentType_Blob);
+ BOOST_CHECK_THROW(MetadataObject metadata(data), tlv::Error);
+
+ // empty content
+ data.setName(Name("ndn/unit/test").append(metadataComponent));
+ BOOST_CHECK_THROW(MetadataObject metadata(data), tlv::Error);
+
+ // non-empty content with no name element
+ data.setContent("F000"_block);
+ BOOST_CHECK_THROW(MetadataObject metadata(data), tlv::Error);
+}
+
+BOOST_AUTO_TEST_CASE(IsValidName)
+{
+ // valid name
+ Name name = Name("/ndn/unit/test")
+ .append(metadataComponent)
+ .appendVersion()
+ .appendSegment(0);
+ BOOST_CHECK(MetadataObject::isValidName(name));
+
+ // invalid names
+ // segment component is missing
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name.getPrefix(-1)), false);
+
+ // version component is missing
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name.getPrefix(-2)), false);
+
+ // keyword name component `32=keyword` is missing
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name.getPrefix(-3)), false);
+
+ // too short name
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name.getPrefix(-4)), false);
+
+ // out-of-order segment and version components
+ name = name.getPrefix(-2).appendSegment(0).appendVersion();
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name), false);
+
+ // invalid name component keyword
+ name = name.getPrefix(-3)
+ .append(32, reinterpret_cast<const uint8_t*>("foo"), std::strlen("foo"))
+ .appendVersion()
+ .appendSegment(0);
+ BOOST_CHECK_EQUAL(MetadataObject::isValidName(name), false);
+}
+
+BOOST_AUTO_TEST_CASE(MakeDiscoveryInterest)
+{
+ Interest interest = MetadataObject::makeDiscoveryInterest(baseContentName);
+ BOOST_CHECK_EQUAL(interest.getName(), Name(baseContentName).append(metadataComponent));
+ BOOST_CHECK(interest.getCanBePrefix());
+ BOOST_CHECK(interest.getMustBeFresh());
+}
+
+BOOST_AUTO_TEST_SUITE_END() // TestMetadataObject
+
+} // namespace tests
+} // namespace ndn