blob: c3979fd2a9687b1795b2d3c4c38723451ed1731e [file] [log] [blame]
Zhuo Lib3558892016-08-12 15:51:12 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Junxiao Shib54aabd2018-04-16 19:36:24 +00002/*
Junxiao Shifd2d1012022-01-11 18:20:38 +00003 * Copyright (c) 2014-2022, Arizona Board of Regents.
Zhuo Lib3558892016-08-12 15:51:12 -07004 *
5 * This file is part of ndn-tools (Named Data Networking Essential Tools).
6 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
7 *
8 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "tools/peek/ndnpeek/ndnpeek.hpp"
21
22#include "tests/test-common.hpp"
Davide Pesavento66777622020-10-09 18:46:03 -040023#include "tests/io-fixture.hpp"
Davide Pesaventobf28cd72017-08-13 17:22:47 -040024
Zhuo Lib3558892016-08-12 15:51:12 -070025#include <ndn-cxx/util/dummy-client-face.hpp>
26
27#include <boost/mpl/vector.hpp>
Davide Pesaventoa8600b02019-12-22 18:52:36 -050028#include <boost/test/tools/output_test_stream.hpp>
Zhuo Lib3558892016-08-12 15:51:12 -070029
Davide Pesaventob3570c62022-02-19 19:19:00 -050030namespace ndn::peek::tests {
Zhuo Lib3558892016-08-12 15:51:12 -070031
32using namespace ndn::tests;
33using boost::test_tools::output_test_stream;
34
35class CoutRedirector : noncopyable
36{
37public:
38 explicit
39 CoutRedirector(std::ostream& destination)
40 {
41 m_originalBuf = std::cout.rdbuf(destination.rdbuf());
42 }
43
44 ~CoutRedirector()
45 {
46 std::cout.rdbuf(m_originalBuf);
47 }
48
49private:
50 std::streambuf* m_originalBuf;
51};
52
Davide Pesavento96028232019-08-17 01:26:13 -040053static PeekOptions
54makeDefaultOptions()
55{
56 PeekOptions opt;
57 opt.name = "/peek/test";
58 return opt;
59}
60
Davide Pesavento66777622020-10-09 18:46:03 -040061class NdnPeekFixture : public IoFixture
Zhuo Lib3558892016-08-12 15:51:12 -070062{
63protected:
Zhuo Lib3558892016-08-12 15:51:12 -070064 void
Davide Pesavento96028232019-08-17 01:26:13 -040065 initialize(const PeekOptions& opts = makeDefaultOptions())
Zhuo Lib3558892016-08-12 15:51:12 -070066 {
67 peek = make_unique<NdnPeek>(face, opts);
68 }
69
70protected:
Davide Pesavento66777622020-10-09 18:46:03 -040071 ndn::util::DummyClientFace face{m_io};
Zhuo Lib3558892016-08-12 15:51:12 -070072 output_test_stream output;
73 unique_ptr<NdnPeek> peek;
74};
75
Zhuo Lib3558892016-08-12 15:51:12 -070076class OutputFull
77{
78public:
79 static PeekOptions
80 makeOptions()
81 {
82 return makeDefaultOptions();
83 }
84
85 static void
86 checkOutput(output_test_stream& output, const Data& data)
87 {
88 const Block& block = data.wireEncode();
Davide Pesavento242d5062022-03-11 16:34:23 -050089 std::string expected(reinterpret_cast<const char*>(block.data()), block.size());
Zhuo Lib3558892016-08-12 15:51:12 -070090 BOOST_CHECK(output.is_equal(expected));
91 }
92
93 static void
94 checkOutput(output_test_stream& output, const lp::Nack& nack)
95 {
96 const Block& block = nack.getHeader().wireEncode();
Davide Pesavento242d5062022-03-11 16:34:23 -050097 std::string expected(reinterpret_cast<const char*>(block.data()), block.size());
Zhuo Lib3558892016-08-12 15:51:12 -070098 BOOST_CHECK(output.is_equal(expected));
99 }
100};
101
102class OutputPayloadOnly
103{
104public:
105 static PeekOptions
106 makeOptions()
107 {
108 PeekOptions opt = makeDefaultOptions();
109 opt.wantPayloadOnly = true;
110 return opt;
111 }
112
113 static void
114 checkOutput(output_test_stream& output, const Data& data)
115 {
116 const Block& block = data.getContent();
117 std::string expected(reinterpret_cast<const char*>(block.value()), block.value_size());
118 BOOST_CHECK(output.is_equal(expected));
119 }
120
121 static void
122 checkOutput(output_test_stream& output, const lp::Nack& nack)
123 {
124 std::string expected = boost::lexical_cast<std::string>(nack.getReason()) + '\n';
125 BOOST_CHECK(output.is_equal(expected));
126 }
127};
128
129BOOST_AUTO_TEST_SUITE(Peek)
130BOOST_FIXTURE_TEST_SUITE(TestNdnPeek, NdnPeekFixture)
131
132using OutputChecks = boost::mpl::vector<OutputFull, OutputPayloadOnly>;
133
134BOOST_AUTO_TEST_CASE_TEMPLATE(Default, OutputCheck, OutputChecks)
135{
136 auto options = OutputCheck::makeOptions();
137 initialize(options);
138
Junxiao Shib54aabd2018-04-16 19:36:24 +0000139 auto data = makeData(options.name);
Davide Pesavento59984282022-02-16 22:41:03 -0500140 data->setContent({'n', 'd', 'n', 'p', 'e', 'e', 'k'});
Zhuo Lib3558892016-08-12 15:51:12 -0700141
142 {
143 CoutRedirector redir(output);
144 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400145 this->advanceClocks(25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700146 face.receive(*data);
147 }
148
149 OutputCheck::checkOutput(output, *data);
150 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Junxiao Shifd2d1012022-01-11 18:20:38 +0000151 const auto& interest = face.sentInterests.back();
152 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), false);
153 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), false);
154 BOOST_CHECK_EQUAL(interest.getForwardingHint().empty(), true);
155 BOOST_CHECK_EQUAL(interest.getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
156 BOOST_CHECK(interest.getHopLimit() == nullopt);
157 BOOST_CHECK(!interest.hasApplicationParameters());
Davide Pesavento87434be2019-07-25 19:04:23 -0400158 BOOST_CHECK(peek->getResult() == NdnPeek::Result::DATA);
Zhuo Lib3558892016-08-12 15:51:12 -0700159}
160
Junxiao Shib54aabd2018-04-16 19:36:24 +0000161BOOST_AUTO_TEST_CASE_TEMPLATE(NonDefault, OutputCheck, OutputChecks)
Zhuo Lib3558892016-08-12 15:51:12 -0700162{
163 auto options = OutputCheck::makeOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000164 options.canBePrefix = true;
Zhuo Lib3558892016-08-12 15:51:12 -0700165 options.mustBeFresh = true;
Junxiao Shifd2d1012022-01-11 18:20:38 +0000166 options.forwardingHint.emplace_back("/fh");
Junxiao Shib54aabd2018-04-16 19:36:24 +0000167 options.interestLifetime = 200_ms;
Davide Pesaventoc214e072019-08-17 01:33:28 -0400168 options.hopLimit = 64;
Zhuo Lib3558892016-08-12 15:51:12 -0700169 initialize(options);
170
Junxiao Shib54aabd2018-04-16 19:36:24 +0000171 auto data = makeData(Name(options.name).append("suffix"));
Junxiao Shi96192952019-05-22 15:45:12 +0000172 data->setFreshnessPeriod(1_s);
Davide Pesavento59984282022-02-16 22:41:03 -0500173 data->setContent({'n', 'd', 'n', 'p', 'e', 'e', 'k'});
Zhuo Lib3558892016-08-12 15:51:12 -0700174
175 {
176 CoutRedirector redir(output);
177 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400178 this->advanceClocks(25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700179 face.receive(*data);
180 }
181
182 OutputCheck::checkOutput(output, *data);
183 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Junxiao Shifd2d1012022-01-11 18:20:38 +0000184 const auto& interest = face.sentInterests.back();
185 BOOST_CHECK_EQUAL(interest.getCanBePrefix(), true);
186 BOOST_CHECK_EQUAL(interest.getMustBeFresh(), true);
187 BOOST_TEST(interest.getForwardingHint() == std::vector<Name>({"/fh"}),
188 boost::test_tools::per_element());
189 BOOST_CHECK_EQUAL(interest.getInterestLifetime(), 200_ms);
190 BOOST_CHECK(interest.getHopLimit() == 64);
191 BOOST_CHECK(!interest.hasApplicationParameters());
Davide Pesavento87434be2019-07-25 19:04:23 -0400192 BOOST_CHECK(peek->getResult() == NdnPeek::Result::DATA);
Zhuo Lib3558892016-08-12 15:51:12 -0700193}
194
195BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithReason, OutputCheck, OutputChecks)
196{
197 auto options = OutputCheck::makeOptions();
198 initialize(options);
199 lp::Nack nack;
200
201 {
202 CoutRedirector redir(output);
203 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400204 this->advanceClocks(25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700205 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NO_ROUTE);
206 face.receive(nack);
207 }
208
209 OutputCheck::checkOutput(output, nack);
210 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400211 BOOST_CHECK(peek->getResult() == NdnPeek::Result::NACK);
Zhuo Lib3558892016-08-12 15:51:12 -0700212}
213
214BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithoutReason, OutputCheck, OutputChecks)
215{
216 auto options = OutputCheck::makeOptions();
217 initialize(options);
218 lp::Nack nack;
219
220 {
221 CoutRedirector redir(output);
222 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400223 this->advanceClocks(25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700224 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NONE);
225 face.receive(nack);
226 }
227
228 OutputCheck::checkOutput(output, nack);
229 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400230 BOOST_CHECK(peek->getResult() == NdnPeek::Result::NACK);
Zhuo Lib3558892016-08-12 15:51:12 -0700231}
232
Davide Pesavento96028232019-08-17 01:26:13 -0400233BOOST_AUTO_TEST_CASE(ApplicationParameters)
234{
235 auto options = makeDefaultOptions();
236 options.applicationParameters = make_shared<Buffer>("hello", 5);
237 initialize(options);
238
239 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400240 this->advanceClocks(25_ms, 4);
Davide Pesavento96028232019-08-17 01:26:13 -0400241
242 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
243 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), false);
244 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), false);
245 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
246 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
247 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), true);
248 BOOST_CHECK_EQUAL(face.sentInterests.back().getApplicationParameters(), "2405 68656C6C6F"_block);
249}
250
Davide Pesavento65d11552019-06-09 19:15:50 -0400251BOOST_AUTO_TEST_CASE(NoTimeout)
Zhuo Lib3558892016-08-12 15:51:12 -0700252{
253 auto options = makeDefaultOptions();
Davide Pesavento65d11552019-06-09 19:15:50 -0400254 options.interestLifetime = 1_s;
Davide Pesavento242d5062022-03-11 16:34:23 -0500255 options.timeout = std::nullopt;
Zhuo Lib3558892016-08-12 15:51:12 -0700256 initialize(options);
257
Davide Pesavento65d11552019-06-09 19:15:50 -0400258 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700259
260 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400261 this->advanceClocks(100_ms, 9);
Zhuo Lib3558892016-08-12 15:51:12 -0700262 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400263 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400264 BOOST_CHECK(peek->getResult() == NdnPeek::Result::UNKNOWN);
Davide Pesavento65d11552019-06-09 19:15:50 -0400265
Davide Pesavento66777622020-10-09 18:46:03 -0400266 this->advanceClocks(100_ms, 2);
Davide Pesavento65d11552019-06-09 19:15:50 -0400267 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
268 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400269 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700270}
271
272BOOST_AUTO_TEST_CASE(TimeoutLessThanLifetime)
273{
274 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000275 options.interestLifetime = 200_ms;
276 options.timeout = 100_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700277 initialize(options);
278
Davide Pesavento65d11552019-06-09 19:15:50 -0400279 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700280
281 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400282 this->advanceClocks(25_ms, 6);
Zhuo Lib3558892016-08-12 15:51:12 -0700283
284 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400285 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400286 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700287}
288
289BOOST_AUTO_TEST_CASE(TimeoutGreaterThanLifetime)
290{
291 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000292 options.interestLifetime = 50_ms;
293 options.timeout = 200_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700294 initialize(options);
295
Davide Pesavento65d11552019-06-09 19:15:50 -0400296 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700297
298 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400299 this->advanceClocks(25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700300
301 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400302 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400303 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700304}
305
Davide Pesavento96028232019-08-17 01:26:13 -0400306BOOST_AUTO_TEST_CASE(OversizedPacket)
307{
308 auto options = makeDefaultOptions();
309 options.applicationParameters = make_shared<Buffer>(MAX_NDN_PACKET_SIZE);
310 initialize(options);
311
312 peek->start();
Davide Pesavento66777622020-10-09 18:46:03 -0400313 BOOST_CHECK_THROW(this->advanceClocks(1_ms, 10), Face::OversizedPacketError);
Davide Pesavento96028232019-08-17 01:26:13 -0400314
315 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
316}
317
Zhuo Lib3558892016-08-12 15:51:12 -0700318BOOST_AUTO_TEST_SUITE_END() // TestNdnPeek
319BOOST_AUTO_TEST_SUITE_END() // Peek
320
Davide Pesaventob3570c62022-02-19 19:19:00 -0500321} // namespace ndn::peek::tests