blob: 73e6bfee29968033b0fcc34a6a9daeb7e445ea7e [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
53class NdnPeekFixture : public UnitTestTimeFixture
54{
55protected:
Zhuo Lib3558892016-08-12 15:51:12 -070056 void
57 initialize(const PeekOptions& opts)
58 {
59 peek = make_unique<NdnPeek>(face, opts);
60 }
61
62protected:
63 boost::asio::io_service io;
Davide Pesavento65d11552019-06-09 19:15:50 -040064 ndn::util::DummyClientFace face{io};
Zhuo Lib3558892016-08-12 15:51:12 -070065 output_test_stream output;
66 unique_ptr<NdnPeek> peek;
67};
68
69static PeekOptions
70makeDefaultOptions()
71{
72 PeekOptions opt;
Junxiao Shib54aabd2018-04-16 19:36:24 +000073 opt.name = "ndn:/peek/test";
Junxiao Shib54aabd2018-04-16 19:36:24 +000074 opt.timeout = 200_ms;
Zhuo Lib3558892016-08-12 15:51:12 -070075 return opt;
76}
77
78class OutputFull
79{
80public:
81 static PeekOptions
82 makeOptions()
83 {
84 return makeDefaultOptions();
85 }
86
87 static void
88 checkOutput(output_test_stream& output, const Data& data)
89 {
90 const Block& block = data.wireEncode();
91 std::string expected(reinterpret_cast<const char*>(block.wire()), block.size());
92 BOOST_CHECK(output.is_equal(expected));
93 }
94
95 static void
96 checkOutput(output_test_stream& output, const lp::Nack& nack)
97 {
98 const Block& block = nack.getHeader().wireEncode();
99 std::string expected(reinterpret_cast<const char*>(block.wire()), block.size());
100 BOOST_CHECK(output.is_equal(expected));
101 }
102};
103
104class OutputPayloadOnly
105{
106public:
107 static PeekOptions
108 makeOptions()
109 {
110 PeekOptions opt = makeDefaultOptions();
111 opt.wantPayloadOnly = true;
112 return opt;
113 }
114
115 static void
116 checkOutput(output_test_stream& output, const Data& data)
117 {
118 const Block& block = data.getContent();
119 std::string expected(reinterpret_cast<const char*>(block.value()), block.value_size());
120 BOOST_CHECK(output.is_equal(expected));
121 }
122
123 static void
124 checkOutput(output_test_stream& output, const lp::Nack& nack)
125 {
126 std::string expected = boost::lexical_cast<std::string>(nack.getReason()) + '\n';
127 BOOST_CHECK(output.is_equal(expected));
128 }
129};
130
131BOOST_AUTO_TEST_SUITE(Peek)
132BOOST_FIXTURE_TEST_SUITE(TestNdnPeek, NdnPeekFixture)
133
134using OutputChecks = boost::mpl::vector<OutputFull, OutputPayloadOnly>;
135
136BOOST_AUTO_TEST_CASE_TEMPLATE(Default, OutputCheck, OutputChecks)
137{
138 auto options = OutputCheck::makeOptions();
139 initialize(options);
140
Junxiao Shib54aabd2018-04-16 19:36:24 +0000141 auto data = makeData(options.name);
Davide Pesavento65d11552019-06-09 19:15:50 -0400142 const std::string payload = "NdnPeekTest";
Zhuo Lib3558892016-08-12 15:51:12 -0700143 data->setContent(reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
144
145 {
146 CoutRedirector redir(output);
147 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000148 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700149 face.receive(*data);
150 }
151
152 OutputCheck::checkOutput(output, *data);
153 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000154 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), false);
Zhuo Lib3558892016-08-12 15:51:12 -0700155 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), false);
Davide Pesavento65d11552019-06-09 19:15:50 -0400156 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000157 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), DEFAULT_INTEREST_LIFETIME);
Davide Pesavento65d11552019-06-09 19:15:50 -0400158 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), false);
Zhuo Lib3558892016-08-12 15:51:12 -0700159 BOOST_CHECK(peek->getResultCode() == ResultCode::DATA);
160}
161
Junxiao Shib54aabd2018-04-16 19:36:24 +0000162BOOST_AUTO_TEST_CASE_TEMPLATE(NonDefault, OutputCheck, OutputChecks)
Zhuo Lib3558892016-08-12 15:51:12 -0700163{
164 auto options = OutputCheck::makeOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000165 options.canBePrefix = true;
Zhuo Lib3558892016-08-12 15:51:12 -0700166 options.mustBeFresh = true;
Junxiao Shib54aabd2018-04-16 19:36:24 +0000167 options.interestLifetime = 200_ms;
Zhuo Lib3558892016-08-12 15:51:12 -0700168 initialize(options);
169
Junxiao Shib54aabd2018-04-16 19:36:24 +0000170 auto data = makeData(Name(options.name).append("suffix"));
Junxiao Shi96192952019-05-22 15:45:12 +0000171 data->setFreshnessPeriod(1_s);
Davide Pesavento65d11552019-06-09 19:15:50 -0400172 const std::string payload = "NdnPeekTest";
Zhuo Lib3558892016-08-12 15:51:12 -0700173 data->setContent(reinterpret_cast<const uint8_t*>(payload.data()), payload.size());
174
175 {
176 CoutRedirector redir(output);
177 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000178 this->advanceClocks(io, 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 Shib54aabd2018-04-16 19:36:24 +0000184 BOOST_CHECK_EQUAL(face.sentInterests.back().getCanBePrefix(), true);
Zhuo Lib3558892016-08-12 15:51:12 -0700185 BOOST_CHECK_EQUAL(face.sentInterests.back().getMustBeFresh(), true);
Davide Pesavento65d11552019-06-09 19:15:50 -0400186 BOOST_CHECK_EQUAL(face.sentInterests.back().getForwardingHint().empty(), true);
Junxiao Shib54aabd2018-04-16 19:36:24 +0000187 BOOST_CHECK_EQUAL(face.sentInterests.back().getInterestLifetime(), 200_ms);
Davide Pesavento65d11552019-06-09 19:15:50 -0400188 BOOST_CHECK_EQUAL(face.sentInterests.back().hasApplicationParameters(), false);
Zhuo Lib3558892016-08-12 15:51:12 -0700189 BOOST_CHECK(peek->getResultCode() == ResultCode::DATA);
190}
191
192BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithReason, OutputCheck, OutputChecks)
193{
194 auto options = OutputCheck::makeOptions();
195 initialize(options);
196 lp::Nack nack;
197
198 {
199 CoutRedirector redir(output);
200 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000201 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700202 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NO_ROUTE);
203 face.receive(nack);
204 }
205
206 OutputCheck::checkOutput(output, nack);
207 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
208 BOOST_CHECK(peek->getResultCode() == ResultCode::NACK);
209}
210
211BOOST_AUTO_TEST_CASE_TEMPLATE(ReceiveNackWithoutReason, OutputCheck, OutputChecks)
212{
213 auto options = OutputCheck::makeOptions();
214 initialize(options);
215 lp::Nack nack;
216
217 {
218 CoutRedirector redir(output);
219 peek->start();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000220 this->advanceClocks(io, 25_ms, 4);
Zhuo Lib3558892016-08-12 15:51:12 -0700221 nack = makeNack(face.sentInterests.at(0), lp::NackReason::NONE);
222 face.receive(nack);
223 }
224
225 OutputCheck::checkOutput(output, nack);
226 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Zhuo Lib3558892016-08-12 15:51:12 -0700227 BOOST_CHECK(peek->getResultCode() == ResultCode::NACK);
228}
229
Davide Pesavento65d11552019-06-09 19:15:50 -0400230BOOST_AUTO_TEST_CASE(NoTimeout)
Zhuo Lib3558892016-08-12 15:51:12 -0700231{
232 auto options = makeDefaultOptions();
Davide Pesavento65d11552019-06-09 19:15:50 -0400233 options.interestLifetime = 1_s;
234 options.timeout = nullopt;
Zhuo Lib3558892016-08-12 15:51:12 -0700235 initialize(options);
236
Davide Pesavento65d11552019-06-09 19:15:50 -0400237 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700238
239 peek->start();
Davide Pesavento65d11552019-06-09 19:15:50 -0400240 this->advanceClocks(io, 100_ms, 9);
Zhuo Lib3558892016-08-12 15:51:12 -0700241 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400242 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 1);
243 BOOST_CHECK(peek->getResultCode() == ResultCode::UNKNOWN);
244
245 this->advanceClocks(io, 100_ms, 2);
246 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
247 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700248 BOOST_CHECK(peek->getResultCode() == ResultCode::TIMEOUT);
249}
250
251BOOST_AUTO_TEST_CASE(TimeoutLessThanLifetime)
252{
253 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000254 options.interestLifetime = 200_ms;
255 options.timeout = 100_ms;
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 Pesavento65d11552019-06-09 19:15:50 -0400261 this->advanceClocks(io, 25_ms, 6);
Zhuo Lib3558892016-08-12 15:51:12 -0700262
263 BOOST_CHECK_EQUAL(face.sentInterests.size(), 1);
Davide Pesavento65d11552019-06-09 19:15:50 -0400264 BOOST_CHECK_EQUAL(face.getNPendingInterests(), 0);
Zhuo Lib3558892016-08-12 15:51:12 -0700265 BOOST_CHECK(peek->getResultCode() == ResultCode::TIMEOUT);
266}
267
268BOOST_AUTO_TEST_CASE(TimeoutGreaterThanLifetime)
269{
270 auto options = makeDefaultOptions();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000271 options.interestLifetime = 50_ms;
272 options.timeout = 200_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();
Junxiao Shib54aabd2018-04-16 19:36:24 +0000278 this->advanceClocks(io, 25_ms, 4);
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);
Zhuo Lib3558892016-08-12 15:51:12 -0700282 BOOST_CHECK(peek->getResultCode() == ResultCode::TIMEOUT);
283}
284
285BOOST_AUTO_TEST_SUITE_END() // TestNdnPeek
286BOOST_AUTO_TEST_SUITE_END() // Peek
287
288} // namespace tests
289} // namespace peek
290} // namespace ndn