blob: d7ab98a27a83a88138e9077202a36a889c42043d [file] [log] [blame]
Davide Pesavento017a9c02022-11-04 18:48:16 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2013-2022 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
22#include "ndn-cxx/util/segmenter.hpp"
23
24#include "tests/boost-test.hpp"
25#include "tests/key-chain-fixture.hpp"
26
27namespace ndn {
28namespace util {
29namespace tests {
30
31using namespace ndn::tests;
32
33BOOST_AUTO_TEST_SUITE(Util)
34BOOST_FIXTURE_TEST_SUITE(TestSegmenter, KeyChainFixture)
35
36BOOST_AUTO_TEST_CASE(Invalid)
37{
38 Segmenter segmenter(m_keyChain, security::SigningInfo{});
39 std::vector<std::shared_ptr<Data>> v;
40
41 const uint8_t arr[] = {1, 2, 3, 4};
42 // maxSegmentSize == 0
43 BOOST_CHECK_THROW(v = segmenter.segment(arr, "/foo", 0, 1_s), std::invalid_argument);
44 std::istringstream ss1("foo");
45 BOOST_CHECK_THROW(v = segmenter.segment(ss1, "/foo", 0, 1_s), std::invalid_argument);
46
47 // negative freshnessPeriod
48 BOOST_CHECK_THROW(v = segmenter.segment(arr, "/foo", 100, -1_s), std::invalid_argument);
49 std::istringstream ss2("foo");
50 BOOST_CHECK_THROW(v = segmenter.segment(ss2, "/foo", 100, -1_s), std::invalid_argument);
51}
52
53BOOST_AUTO_TEST_CASE(EmptyInput)
54{
55 Segmenter segmenter(m_keyChain, security::SigningInfo{});
56
57 auto check = [] (const auto& v) {
58 BOOST_REQUIRE_EQUAL(v.size(), 1);
59 BOOST_TEST(v[0]->getName() == "/empty/seg=0");
60 BOOST_TEST(v[0]->getContentType() == tlv::ContentType_Nack);
61 BOOST_TEST(v[0]->getFreshnessPeriod() == 1_s);
62 BOOST_TEST(v[0]->getFinalBlock().value() == name::Component::fromSegment(0));
63 BOOST_TEST(v[0]->getContent().value_size() == 0);
64 };
65
66 check(segmenter.segment(span<uint8_t>{}, "/empty", 1000, 1_s, tlv::ContentType_Nack));
67 std::istringstream ss;
68 check(segmenter.segment(ss, "/empty", 1000, 1_s, tlv::ContentType_Nack));
69}
70
71BOOST_AUTO_TEST_CASE(OneSegment)
72{
73 Segmenter segmenter(m_keyChain, security::SigningInfo{});
74
75 auto check = [] (const auto& v, size_t expectedContentSize) {
76 BOOST_REQUIRE_EQUAL(v.size(), 1);
77 BOOST_TEST(v[0]->getName() == "/one/seg=0");
78 BOOST_TEST(v[0]->getContentType() == tlv::ContentType_Blob);
79 BOOST_TEST(v[0]->getFreshnessPeriod() == 1_min);
80 BOOST_TEST(v[0]->getFinalBlock().value() == name::Component::fromSegment(0));
81 BOOST_TEST(v[0]->getContent().value_size() == expectedContentSize);
82 };
83
84 const uint8_t arr1[] = {1, 2, 3, 4};
85 check(segmenter.segment(arr1, "/one", 10, 1_min), sizeof(arr1));
86 std::istringstream ss1("1234");
87 check(segmenter.segment(ss1, "/one", 10, 1_min), 4);
88
89 const uint8_t arr2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
90 check(segmenter.segment(arr2, "/one", 10, 1_min), sizeof(arr2));
91 std::istringstream ss2("1234567890");
92 check(segmenter.segment(ss2, "/one", 10, 1_min), 10);
93}
94
95const uint8_t BLOB[] = { // 300 bytes
96 0x06, 0xFD, 0x01, 0xBB, 0x07, 0x33, 0x08, 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x05, 0x73, 0x69, 0x74,
97 0x65, 0x31, 0x08, 0x03, 0x4B, 0x45, 0x59, 0x08, 0x11, 0x6B, 0x73, 0x6B, 0x2D, 0x31, 0x34, 0x31,
98 0x36, 0x34, 0x32, 0x35, 0x33, 0x37, 0x37, 0x30, 0x39, 0x34, 0x08, 0x04, 0x30, 0x31, 0x32, 0x33,
99 0x08, 0x07, 0xFD, 0x00, 0x00, 0x01, 0x49, 0xC9, 0x8B, 0x14, 0x09, 0x18, 0x01, 0x02, 0x19, 0x04,
100 0x00, 0x36, 0xEE, 0x80, 0x15, 0xA0, 0x30, 0x81, 0x9D, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48,
101 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8B, 0x00, 0x30, 0x81, 0x87, 0x02,
102 0x81, 0x81, 0x00, 0x9E, 0x06, 0x3E, 0x47, 0x85, 0xB2, 0x34, 0x37, 0xAA, 0x85, 0x47, 0xAC, 0x03,
103 0x24, 0x83, 0xB5, 0x9C, 0xA8, 0x05, 0x3A, 0x24, 0x1E, 0xEB, 0x89, 0x01, 0xBB, 0xE9, 0x9B, 0xB2,
104 0xC3, 0x22, 0xAC, 0x68, 0xE3, 0xF0, 0x6C, 0x02, 0xCE, 0x68, 0xA6, 0xC4, 0xD0, 0xA7, 0x06, 0x90,
105 0x9C, 0xAA, 0x1B, 0x08, 0x1D, 0x8B, 0x43, 0x9A, 0x33, 0x67, 0x44, 0x6D, 0x21, 0xA3, 0x1B, 0x88,
106 0x9A, 0x97, 0x5E, 0x59, 0xC4, 0x15, 0x0B, 0xD9, 0x2C, 0xBD, 0x51, 0x07, 0x61, 0x82, 0xAD, 0xC1,
107 0xB8, 0xD7, 0xBF, 0x9B, 0xCF, 0x7D, 0x24, 0xC2, 0x63, 0xF3, 0x97, 0x17, 0xEB, 0xFE, 0x62, 0x25,
108 0xBA, 0x5B, 0x4D, 0x8A, 0xC2, 0x7A, 0xBD, 0x43, 0x8A, 0x8F, 0xB8, 0xF2, 0xF1, 0xC5, 0x6A, 0x30,
109 0xD3, 0x50, 0x8C, 0xC8, 0x9A, 0xDF, 0xEF, 0xED, 0x35, 0xE7, 0x7A, 0x62, 0xEA, 0x76, 0x7C, 0xBB,
110 0x08, 0x26, 0xC7, 0x02, 0x01, 0x11, 0x16, 0x55, 0x1B, 0x01, 0x01, 0x1C, 0x26, 0x07, 0x24, 0x08,
111 0x03, 0x6E, 0x64, 0x6E, 0x08, 0x05, 0x73, 0x69, 0x74, 0x65, 0x31, 0x08, 0x03, 0x4B, 0x45, 0x59,
112 0x08, 0x11, 0x6B, 0x73, 0x6B, 0x2D, 0x32, 0x35, 0x31, 0x36, 0x34, 0x32, 0x35, 0x33, 0x37, 0x37,
113 0x30, 0x39, 0x34, 0xFD, 0x00, 0xFD, 0x26, 0xFD, 0x00, 0xFE, 0x0F, 0x17, 0x80, 0xFF, 0xFF, 0xFF,
114 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
115};
116
117BOOST_AUTO_TEST_CASE(MultipleSegments)
118{
119 Segmenter segmenter(m_keyChain, security::SigningInfo{});
120
121 auto check = [] (const auto& v) {
122 BOOST_TEST(v.size() == 8);
123
124 size_t segNo = 0;
125 for (const auto& seg : v) {
126 BOOST_TEST(seg->getName().getPrefix(-1) == "/many");
127 BOOST_TEST(seg->getName().at(-1).toSegment() == segNo);
128 BOOST_TEST(seg->getContentType() == tlv::ContentType_Blob);
129 BOOST_TEST(seg->getFreshnessPeriod() == 30_s);
130 BOOST_TEST(seg->getFinalBlock().value() == name::Component::fromSegment(7));
131 // last segment is shorter
132 const size_t expectedContentSize = segNo == 7 ? (sizeof(BLOB) % 42) : 42;
133 BOOST_TEST(seg->getContent().value_bytes() == make_span(BLOB).subspan(segNo * 42, expectedContentSize),
134 boost::test_tools::per_element());
135 segNo++;
136 }
137 };
138
139 check(segmenter.segment(BLOB, "/many", 42, 30_s));
140 std::istringstream ss(std::string(reinterpret_cast<const char*>(BLOB), sizeof(BLOB)));
141 check(segmenter.segment(ss, "/many", 42, 30_s));
142}
143
144BOOST_AUTO_TEST_SUITE_END() // TestSegmenter
145BOOST_AUTO_TEST_SUITE_END() // Util
146
147} // namespace tests
148} // namespace util
149} // namespace ndn