blob: f144d5abaa2e0893c257070a62c7832130657a11 [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 Shi96192952019-05-22 15:45:12 +00003 * Copyright (c) 2014-2019, 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 Pesaventobf28cd72017-08-13 17:22:47 -040023
Zhuo Lib3558892016-08-12 15:51:12 -070024#include <ndn-cxx/util/dummy-client-face.hpp>
25
26#include <boost/mpl/vector.hpp>
27
28namespace ndn {
29namespace peek {
30namespace tests {
31
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
Zhuo Lib3558892016-08-12 15:51:12 -070061class NdnPeekFixture : public UnitTestTimeFixture
62{
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:
71 boost::asio::io_service io;
Davide Pesavento65d11552019-06-09 19:15:50 -040072 ndn::util::DummyClientFace face{io};
Zhuo Lib3558892016-08-12 15:51:12 -070073 output_test_stream output;
74 unique_ptr<NdnPeek> peek;
75};
76
Zhuo Lib3558892016-08-12 15:51:12 -070077class OutputFull
78{
79public:
80 static PeekOptions
81 makeOptions()
82 {
83 return makeDefaultOptions();
84 }
85
86 static void
87 checkOutput(output_test_stream& output, const Data& data)
88 {
89 const Block& block = data.wireEncode();
90 std::string expected(reinterpret_cast<const char*>(block.wire()), block.size());
91 BOOST_CHECK(output.is_equal(expected));
92 }
93
94 static void
95 checkOutput(output_test_stream& output, const lp::Nack& nack)
96 {
97 const Block& block = nack.getHeader().wireEncode();
98 std::string expected(reinterpret_cast<const char*>(block.wire()), block.size());
99 BOOST_CHECK(output.is_equal(expected));
100 }
101};
102
103class OutputPayloadOnly
104{
105public:
106 static PeekOptions
107 makeOptions()
108 {
109 PeekOptions opt = makeDefaultOptions();
110 opt.wantPayloadOnly = true;
111 return opt;
112 }
113
114 static void
115 checkOutput(output_test_stream& output, const Data& data)
116 {
117 const Block& block = data.getContent();
118 std::string expected(reinterpret_cast<const char*>(block.value()), block.value_size());
119 BOOST_CHECK(output.is_equal(expected));
120 }
121
122 static void
123 checkOutput(output_test_stream& output, const lp::Nack& nack)
124 {
125 std::string expected = boost::lexical_cast<std::string>(nack.getReason()) + '\n';
126 BOOST_CHECK(output.is_equal(expected));
127 }
128};
129
130BOOST_AUTO_TEST_SUITE(Peek)
131BOOST_FIXTURE_TEST_SUITE(TestNdnPeek, NdnPeekFixture)
132
133using OutputChecks = boost::mpl::vector<OutputFull, OutputPayloadOnly>;
134
135BOOST_AUTO_TEST_CASE_TEMPLATE(Default, OutputCheck, OutputChecks)
136{
137 auto options = OutputCheck::makeOptions();
138 initialize(options);
139
Junxiao Shib54aabd2018-04-16 19:36:24 +0000140 auto data = makeData(options.name);
Davide Pesavento65d11552019-06-09 19:15:50 -0400141 const std::string payload = "NdnPeekTest";
Zhuo Lib3558892016-08-12 15:51:12 -0700142 data->setContent(reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
143
144 {
145 CoutRedirector redir(output);
146 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000147 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700148 face.receive(*data);
149 }
150
151 OutputCheck::checkOutput(output, *data);
152 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000153 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), false);
Zhuo Lib3558892016-08-12 15:51:12 -0700154 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), false);
Davide Pesavento65d11552019-06-09 19:15:50 -0400155 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000156 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
Davide Pesavento65d11552019-06-09 19:15:50 -0400157 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), false);
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 Shib54aabd2018-04-16 19:36:24 +0000166 options.interestLifetime = 200_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700167 initialize(options);
168
Junxiao Shib54aabd2018-04-16 19:36:24 +0000169 auto data = makeData(Name(options.name).append("suffix"));
Junxiao Shi96192952019-05-22 15:45:12 +0000170 data->setFreshnessPeriod(1_s);
Davide Pesavento65d11552019-06-09 19:15:50 -0400171 const std::string payload = "NdnPeekTest";
Zhuo Lib3558892016-08-12 15:51:12 -0700172 data->setContent(reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
173
174 {
175 CoutRedirector redir(output);
176 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000177 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700178 face.receive(*data);
179 }
180
181 OutputCheck::checkOutput(output, *data);
182 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000183 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), true);
Zhuo Lib3558892016-08-12 15:51:12 -0700184 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), true);
Davide Pesavento65d11552019-06-09 19:15:50 -0400185 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000186 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), 200_ms);
Davide Pesavento65d11552019-06-09 19:15:50 -0400187 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), false);
Davide Pesavento87434be2019-07-25 19:04:23 -0400188 BOOST_CHECK(peek->getResult() == NdnPeek::Result::DATA);
Zhuo Lib3558892016-08-12 15:51:12 -0700189}
190
191BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithReason, OutputCheck, OutputChecks)
192{
193 auto options = OutputCheck::makeOptions();
194 initialize(options);
195 lp::Nack nack;
196
197 {
198 CoutRedirector redir(output);
199 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000200 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700201 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NO_ROUTE);
202 face.receive(nack);
203 }
204
205 OutputCheck::checkOutput(output, nack);
206 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400207 BOOST_CHECK(peek->getResult() == NdnPeek::Result::NACK);
Zhuo Lib3558892016-08-12 15:51:12 -0700208}
209
210BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithoutReason, OutputCheck, OutputChecks)
211{
212 auto options = OutputCheck::makeOptions();
213 initialize(options);
214 lp::Nack nack;
215
216 {
217 CoutRedirector redir(output);
218 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000219 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700220 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NONE);
221 face.receive(nack);
222 }
223
224 OutputCheck::checkOutput(output, nack);
225 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400226 BOOST_CHECK(peek->getResult() == NdnPeek::Result::NACK);
Zhuo Lib3558892016-08-12 15:51:12 -0700227}
228
Davide Pesavento96028232019-08-17 01:26:13 -0400229BOOST_AUTO_TEST_CASE(ApplicationParameters)
230{
231 auto options = makeDefaultOptions();
232 options.applicationParameters = make_shared<Buffer>("hello", 5);
233 initialize(options);
234
235 peek->start();
236 this->advanceClocks(io, 25_ms, 4);
237
238 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
239 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), false);
240 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), false);
241 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
242 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
243 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), true);
244 BOOST_CHECK_EQUAL(face.sentInterests.back().getApplicationParameters(), "2405 68656C6C6F"_block);
245}
246
Davide Pesavento65d11552019-06-09 19:15:50 -0400247BOOST_AUTO_TEST_CASE(NoTimeout)
Zhuo Lib3558892016-08-12 15:51:12 -0700248{
249 auto options = makeDefaultOptions();
Davide Pesavento65d11552019-06-09 19:15:50 -0400250 options.interestLifetime = 1_s;
251 options.timeout = nullopt;
Zhuo Lib3558892016-08-12 15:51:12 -0700252 initialize(options);
253
Davide Pesavento65d11552019-06-09 19:15:50 -0400254 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700255
256 peek->start();
Davide Pesavento65d11552019-06-09 19:15:50 -0400257 this->advanceClocks(io, 100_ms, 9);
Zhuo Lib3558892016-08-12 15:51:12 -0700258 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400259 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
Davide Pesavento87434be2019-07-25 19:04:23 -0400260 BOOST_CHECK(peek->getResult() == NdnPeek::Result::UNKNOWN);
Davide Pesavento65d11552019-06-09 19:15:50 -0400261
262 this->advanceClocks(io, 100_ms, 2);
263 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
264 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400265 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700266}
267
268BOOST_AUTO_TEST_CASE(TimeoutLessThanLifetime)
269{
270 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000271 options.interestLifetime = 200_ms;
272 options.timeout = 100_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700273 initialize(options);
274
Davide Pesavento65d11552019-06-09 19:15:50 -0400275 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700276
277 peek->start();
Davide Pesavento65d11552019-06-09 19:15:50 -0400278 this->advanceClocks(io, 25_ms, 6);
Zhuo Lib3558892016-08-12 15:51:12 -0700279
280 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400281 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400282 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700283}
284
285BOOST_AUTO_TEST_CASE(TimeoutGreaterThanLifetime)
286{
287 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000288 options.interestLifetime = 50_ms;
289 options.timeout = 200_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700290 initialize(options);
291
Davide Pesavento65d11552019-06-09 19:15:50 -0400292 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700293
294 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000295 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700296
297 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400298 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Davide Pesavento87434be2019-07-25 19:04:23 -0400299 BOOST_CHECK(peek->getResult() == NdnPeek::Result::TIMEOUT);
Zhuo Lib3558892016-08-12 15:51:12 -0700300}
301
Davide Pesavento96028232019-08-17 01:26:13 -0400302BOOST_AUTO_TEST_CASE(OversizedPacket)
303{
304 auto options = makeDefaultOptions();
305 options.applicationParameters = make_shared<Buffer>(MAX_NDN_PACKET_SIZE);
306 initialize(options);
307
308 peek->start();
309 BOOST_CHECK_THROW(this->advanceClocks(io, 1_ms, 10), Face::OversizedPacketError);
310
311 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
312}
313
Zhuo Lib3558892016-08-12 15:51:12 -0700314BOOST_AUTO_TEST_SUITE_END() // TestNdnPeek
315BOOST_AUTO_TEST_SUITE_END() // Peek
316
317} // namespace tests
318} // namespace peek
319} // namespace ndn