blob: 55db76565ed0751e5e3c2a9be53c937c3265d569 [file] [log] [blame]
Ashlesh Gawandeec43b362018-08-01 15:15:01 -05001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Ashlesh Gawande5a895472020-01-25 18:07:32 -08003 * Copyright (c) 2014-2020, The University of Memphis
Ashlesh Gawandeec43b362018-08-01 15:15:01 -05004 *
5 * This file is part of PSync.
6 * See AUTHORS.md for complete list of PSync authors and contributors.
7 *
8 * PSync is free software: you can redistribute it and/or modify it under the terms
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -06009 * of the GNU Lesser General Public License as published by the Free Software Foundation,
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050010 * either version 3 of the License, or (at your option) any later version.
11 *
12 * PSync 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
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -060014 * PURPOSE. See the GNU Lesser General Public License for more details.
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050015 *
Ashlesh Gawande0cf4b602019-01-18 15:58:17 -060016 * You should have received a copy of the GNU Lesser General Public License along with
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050017 * PSync, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 **/
19
Ashlesh Gawande78b94ad2018-12-13 15:29:19 -060020#include "PSync/segment-publisher.hpp"
21#include "PSync/detail/state.hpp"
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050022
Davide Pesavento5b3cf762020-04-03 16:20:04 -040023#include "tests/boost-test.hpp"
24#include "tests/unit-test-time-fixture.hpp"
25
Ashlesh Gawandeec43b362018-08-01 15:15:01 -050026#include <ndn-cxx/data.hpp>
27#include <ndn-cxx/interest.hpp>
28#include <ndn-cxx/util/dummy-client-face.hpp>
29#include <ndn-cxx/util/segment-fetcher.hpp>
30#include <ndn-cxx/security/validator-null.hpp>
31
32namespace psync {
33
34using namespace ndn;
35
36class SegmentPublisherFixture : public tests::UnitTestTimeFixture
37{
38public:
39 SegmentPublisherFixture()
40 : face(io, util::DummyClientFace::Options{true, true})
41 , publisher(face, keyChain)
42 , freshness(1000)
43 , numComplete(0)
44 , numRepliesFromStore(0)
45 {
46 face.setInterestFilter(InterestFilter("/hello/world"),
47 bind(&SegmentPublisherFixture::onInterest, this, _1, _2),
48 [] (const ndn::Name& prefix, const std::string& msg) {
49 BOOST_CHECK(false);
50 });
51 advanceClocks(ndn::time::milliseconds(10));
52
53 for (int i = 0; i < 1000; ++i) {
54 state.addContent(Name("/test").appendNumber(i));
55 }
56 }
57
58 ~SegmentPublisherFixture() {
59 fetcher->stop();
60 }
61
62 void
63 expressInterest(const Interest& interest) {
64 fetcher = util::SegmentFetcher::start(face, interest, ndn::security::v2::getAcceptAllValidator());
65 fetcher->onComplete.connect([this] (ConstBufferPtr data) {
66 numComplete++;
67 });
68 fetcher->onError.connect([] (uint32_t errorCode, const std::string& msg) {
69 BOOST_CHECK(false);
70 });
71
72 advanceClocks(ndn::time::milliseconds(10));
73 }
74
75 void
76 onInterest(const Name& prefix, const Interest& interest) {
77 if (publisher.replyFromStore(interest.getName())) {
78 numRepliesFromStore++;
79 return;
80 }
81
82 // If dataName is same as interest name
83 if (dataName.empty()) {
84 publisher.publish(interest.getName(), interest.getName(), state.wireEncode(), freshness);
85 }
86 else {
87 publisher.publish(interest.getName(), dataName, state.wireEncode(), freshness);
88 }
89 }
90
91 util::DummyClientFace face;
92 KeyChain keyChain;
93 SegmentPublisher publisher;
94 shared_ptr<util::SegmentFetcher> fetcher;
95 Name dataName;
96 time::milliseconds freshness;
97 State state;
98
99 int numComplete;
100 int numRepliesFromStore;
101};
102
103BOOST_FIXTURE_TEST_SUITE(TestSegmentPublisher, SegmentPublisherFixture)
104
105BOOST_AUTO_TEST_CASE(Basic)
106{
107 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 0);
108 expressInterest(Interest("/hello/world"));
109 BOOST_CHECK_EQUAL(numComplete, 1);
110 // First segment is answered directly in publish,
111 // Rest two are satisfied by the store
112 BOOST_CHECK_EQUAL(numRepliesFromStore, 2);
113 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 3);
114
115 numRepliesFromStore = 0;
116 expressInterest(Interest("/hello/world"));
117 BOOST_CHECK_EQUAL(numComplete, 2);
118 BOOST_CHECK_EQUAL(numRepliesFromStore, 3);
119
120 advanceClocks(ndn::time::milliseconds(freshness));
121 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 0);
122
123 numRepliesFromStore = 0;
124 expressInterest(Interest("/hello/world"));
125 BOOST_CHECK_EQUAL(numComplete, 3);
126 BOOST_CHECK_EQUAL(numRepliesFromStore, 2);
127
128 numRepliesFromStore = 0;
Junxiao Shi3426baf2019-01-13 23:19:23 +0000129 face.expressInterest(Interest("/hello/world/").setCanBePrefix(true),
Ashlesh Gawandeec43b362018-08-01 15:15:01 -0500130 [this] (const Interest& interest, const Data& data) {
131 numComplete++;
132 },
133 [] (const Interest& interest, const lp::Nack& nack) {
134 BOOST_CHECK(false);
135 },
136 [] (const Interest& interest) {
137 BOOST_CHECK(false);
138 });
139 advanceClocks(ndn::time::milliseconds(10));
140 BOOST_CHECK_EQUAL(numComplete, 4);
141 BOOST_CHECK_EQUAL(numRepliesFromStore, 1);
142}
143
144BOOST_AUTO_TEST_CASE(LargerDataName)
145{
146 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 0);
147 dataName = Name("/hello/world/IBF");
148
149 expressInterest(Interest("/hello/world"));
150 BOOST_CHECK_EQUAL(numComplete, 1);
151 // First segment is answered directly in publish,
152 // Rest two are satisfied by the store
153 BOOST_CHECK_EQUAL(numRepliesFromStore, 2);
154 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 3);
155
156 advanceClocks(ndn::time::milliseconds(freshness));
157 BOOST_CHECK_EQUAL(publisher.m_ims.size(), 0);
158}
159
160BOOST_AUTO_TEST_SUITE_END()
161
Junxiao Shi3426baf2019-01-13 23:19:23 +0000162} // namespace psync