Create utility method to generate file manifests
Refs: #3431
Change-Id: I1a0f06b87689e71349b4fa9346ebc29e785d86cc
diff --git a/tests/unit-tests/file-manifest.t.cpp b/tests/unit-tests/file-manifest.t.cpp
index a8181ad..d6a3e68 100644
--- a/tests/unit-tests/file-manifest.t.cpp
+++ b/tests/unit-tests/file-manifest.t.cpp
@@ -25,11 +25,21 @@
#include <vector>
#include <ndn-cxx/data.hpp>
-#include <ndn-cxx/signature.hpp>
#include <ndn-cxx/security/key-chain.hpp>
+#include <ndn-cxx/security/signing-helpers.hpp>
+#include <ndn-cxx/signature.hpp>
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/lexical_cast.hpp>
+
+namespace fs = boost::filesystem;
BOOST_TEST_DONT_PRINT_LOG_VALUE(std::nullptr_t)
BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::Name>)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::ntorrent::FileManifest>)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<uint8_t>)
+BOOST_TEST_DONT_PRINT_LOG_VALUE(std::vector<ndn::Data>::iterator)
namespace ndn {
namespace ntorrent {
@@ -289,6 +299,117 @@
BOOST_CHECK_EQUAL(m1, m2);
}
+BOOST_AUTO_TEST_CASE(CheckGenerateFileManifest)
+{
+ const size_t TEST_FILE_LEN = fs::file_size("tests/testdata/foo/bar.txt");
+ const struct {
+ size_t d_dataPacketSize;
+ size_t d_subManifestSize;
+ const char *d_filePath;
+ const char *d_catalogPrefix;
+ bool d_getData;
+ bool d_shouldThrow;
+ } DATA [] = {
+ // Affirmative tests
+ {1 , TEST_FILE_LEN, "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ {10 , 10 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ {10 , 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ {1 , 10 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ {1 , 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ {1024 , 1 , "tests/testdata/foo/bar1.txt", "/NTORRENT/foo/", true, false },
+ {1024 , 100 , "tests/testdata/foo/bar1.txt", "/NTORRENT/foo/", true, false },
+ {TEST_FILE_LEN, 1 , "tests/testdata/foo/bar.txt" , "/NTORRENT/foo/", true, false },
+ // Negative tests
+ // non-existent file
+ {128 , 128 , "tests/testdata/foo/fake.txt", "/NTORRENT/foo/", false, true },
+ // prefix mismatch
+ {128 , 128 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", false, true },
+ // scaling test
+ // {10240 , 5120 , "tests/testdata/foo/huge_file", "/NTORRENT/foo/", false, false },
+ // assertion failures (tests not supported on platforms)
+ // {0 , 128 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", true },
+ // {128 , 0 , "tests/testdata/foo/bar.txt", "/NTORRENT/bar/", true },
+ };
+ enum { NUM_DATA = sizeof DATA / sizeof *DATA };
+ for (int i = 0; i < NUM_DATA; ++i) {
+ auto dataPacketSize = DATA[i].d_dataPacketSize;
+ auto subManifestSize = DATA[i].d_subManifestSize;
+ auto filePath = DATA[i].d_filePath;
+ auto catalogPrefix = DATA[i].d_catalogPrefix;
+ auto getData = DATA[i].d_getData;
+ auto shouldThrow = DATA[i].d_shouldThrow;
+
+ std::pair<std::vector<FileManifest>, std::vector<Data>> manifestsDataPair;
+ if (shouldThrow) {
+ BOOST_CHECK_THROW(FileManifest::generate(filePath,
+ catalogPrefix,
+ subManifestSize,
+ dataPacketSize,
+ getData),
+ FileManifest::Error);
+ }
+ else {
+ manifestsDataPair = FileManifest::generate(filePath,
+ catalogPrefix,
+ subManifestSize,
+ dataPacketSize,
+ getData);
+ auto manifests = manifestsDataPair.first;
+ auto data = manifestsDataPair.second;
+ // Verify the basic attributes of the manifest
+ size_t file_length = 0;
+ for (auto it = manifests.begin(); it != manifests.end(); ++it) {
+ // Verify that each file manifest is signed.
+ BOOST_CHECK_NO_THROW(it->getFullName());
+ BOOST_CHECK_EQUAL(it->data_packet_size(), dataPacketSize);
+ BOOST_CHECK_EQUAL(it->catalog_prefix(), catalogPrefix);
+ if (it != manifests.end() -1) {
+ BOOST_CHECK_EQUAL(it->catalog().size(), subManifestSize);
+ BOOST_CHECK_EQUAL(*(it->submanifest_ptr()), (it+1)->getFullName());
+ }
+ else {
+ BOOST_CHECK_LE(it->catalog().size(), subManifestSize);
+ BOOST_CHECK_EQUAL(it->submanifest_ptr(), nullptr);
+ file_length += it->wireEncode().value_size();
+ }
+ }
+ // confirm the manifests catalogs includes exactly the data packets
+ if (getData) {
+ auto data_it = data.begin();
+ size_t total_manifest_length = 0;
+ for (auto& m : manifests) {
+ total_manifest_length += m.wireEncode().value_size();
+ for (auto& data_name : m.catalog()) {
+ BOOST_CHECK_EQUAL(data_name, data_it->getFullName());
+ data_it++;
+ }
+ }
+ BOOST_CHECK_EQUAL(data_it, data.end());
+ std::vector<uint8_t> data_bytes;
+ data_bytes.reserve(fs::file_size(filePath));
+ for (const auto& d : data) {
+ auto content = d.getContent();
+ data_bytes.insert(data_bytes.end(), content.value_begin(), content.value_end());
+ }
+ data_bytes.shrink_to_fit();
+ // load the contents of the file from disk
+ fs::ifstream is(filePath, fs::ifstream::binary | fs::ifstream::in);
+ is >> std::noskipws;
+ std::istream_iterator<uint8_t> start(is), end;
+ std::vector<uint8_t> file_bytes;
+ file_bytes.reserve(fs::file_size(filePath));
+ file_bytes.insert(file_bytes.begin(), start, end);
+ file_bytes.shrink_to_fit();
+ BOOST_CHECK_EQUAL(file_bytes, data_bytes);
+ }
+ else {
+ BOOST_CHECK(data.empty());
+ BOOST_CHECK(data.capacity() == 0);
+ }
+ }
+ }
+}
+
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests