blob: 32304fb7fbe6d71d722132c4211e09f42432d794 [file] [log] [blame]
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyev1cf5c432017-01-13 23:22:15 -08003 * Copyright (c) 2013-2017, Regents of the University of California.
Alexander Afanasyev21a166e2013-01-20 16:04:41 -08004 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08005 * This file is part of ChronoShare, a decentralized file sharing application over NDN.
Alexander Afanasyev21a166e2013-01-20 16:04:41 -08006 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -08007 * ChronoShare is free software: you can redistribute it and/or modify it under the terms
8 * of the GNU General Public License as published by the Free Software Foundation, either
9 * version 3 of the License, or (at your option) any later version.
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080010 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080011 * ChronoShare 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 General Public License for more details.
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080014 *
Alexander Afanasyevfa2f6622016-12-25 12:28:00 -080015 * You should have received copies of the GNU General Public License along with
16 * ChronoShare, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * See AUTHORS.md for complete list of ChronoShare authors and contributors.
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080019 */
Alexander Afanasyevf4cde4e2016-12-25 13:42:57 -080020#include "fetch-manager.hpp"
Yukai Tu35963e02016-10-24 13:48:01 -070021
22#include "test-common.hpp"
23
24#include <ndn-cxx/util/dummy-client-face.hpp>
25
26#include <boost/lexical_cast.hpp>
27#include <boost/algorithm/string/join.hpp>
28#include <boost/range/adaptor/transformed.hpp>
29
30namespace ndn {
31namespace chronoshare {
32namespace tests {
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080033
Alexander Afanasyev1cf5c432017-01-13 23:22:15 -080034_LOG_INIT(Test.FetchManager);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080035
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080036BOOST_AUTO_TEST_SUITE(TestFetchManager)
37
Yukai Tu35963e02016-10-24 13:48:01 -070038class FetcherTestData : public IdentityManagementTimeFixture
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080039{
Yukai Tu35963e02016-10-24 13:48:01 -070040public:
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080041 FetcherTestData()
Yukai Tu35963e02016-10-24 13:48:01 -070042 : face(m_io, m_keyChain, {true, true})
43 , m_done(false)
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080044 , m_failed(false)
Yukai Tu35963e02016-10-24 13:48:01 -070045 , m_hasMissing(true)
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080046 {
47 }
48
49 void
Yukai Tu35963e02016-10-24 13:48:01 -070050 onData(const ndn::Name& deviceName, const ndn::Name& basename, uint64_t seqno,
51 ndn::shared_ptr<ndn::Data> data)
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080052 {
Yukai Tu35963e02016-10-24 13:48:01 -070053 _LOG_TRACE("onData: " << seqno << data->getName());
Alexander Afanasyev1d1cc832013-02-05 20:03:36 -080054
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080055 recvData.insert(seqno);
56 differentNames.insert(basename);
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080057 Name name = basename;
Yukai Tu35963e02016-10-24 13:48:01 -070058 name.appendNumber(seqno);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080059 segmentNames.insert(name);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080060
Yukai Tu35963e02016-10-24 13:48:01 -070061 Block block = data->getContent();
62 std::string recvNo(reinterpret_cast<const char*>(block.value()), block.value_size());
63 recvContent.insert(boost::lexical_cast<uint32_t>(recvNo));
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080064 }
65
66 void
Yukai Tu35963e02016-10-24 13:48:01 -070067 finish(const ndn::Name& deviceName, const ndn::Name& baseName)
Zhenkai Zhu3d1beca2013-01-23 14:55:32 -080068 {
69 }
70
71 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080072 onComplete(Fetcher& fetcher)
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080073 {
74 m_done = true;
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080075 }
76
77 void
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080078 onFail(Fetcher& fetcher)
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080079 {
80 m_failed = true;
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080081 }
Yukai Tu35963e02016-10-24 13:48:01 -070082
83public:
84 util::DummyClientFace face;
85 std::set<uint32_t> recvData;
86 std::set<uint32_t> recvContent;
87
88 std::set<Name> differentNames;
89 std::set<Name> segmentNames;
90
91 bool m_done;
92 bool m_failed;
93
94 bool m_hasMissing;
Alexander Afanasyev21a166e2013-01-20 16:04:41 -080095};
96
Yukai Tu35963e02016-10-24 13:48:01 -070097BOOST_FIXTURE_TEST_CASE(TestFetcher, FetcherTestData)
Yingdi Yuf0b3de32013-07-11 12:59:00 -070098{
Yukai Tu35963e02016-10-24 13:48:01 -070099 Name baseName("/fetchtest");
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800100 Name deviceName("/device");
Yukai Tu35963e02016-10-24 13:48:01 -0700101
102 // publish seqnos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, <gap 5>, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, <gap 1>, 26
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800103 // this will allow us to test our pipeline of 6
Yukai Tu35963e02016-10-24 13:48:01 -0700104 std::set<uint32_t> seqs = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /*<gap 10-14>,*/
105 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, /*<gap 25>,*/ 26};
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800106
Yukai Tu35963e02016-10-24 13:48:01 -0700107 face.onSendInterest.connect([&, this] (const Interest& interest) {
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800108
Yukai Tu35963e02016-10-24 13:48:01 -0700109 uint32_t requestedSeqNo = interest.getName().at(-1).toNumber();
110 if (seqs.count(requestedSeqNo) > 0) {
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800111
Yukai Tu35963e02016-10-24 13:48:01 -0700112 auto data = make_shared<Data>();
113 Name name(baseName);
114 name.appendNumber(requestedSeqNo);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800115
Yukai Tu35963e02016-10-24 13:48:01 -0700116 data->setName(name);
117 data->setFreshnessPeriod(time::seconds(300));
118 std::string content = to_string(requestedSeqNo);
119 data->setContent(reinterpret_cast<const uint8_t*>(content.data()), content.size());
120 m_keyChain.sign(*data);
121 m_io.post([data, this] { face.receive(*data); });
122 }
123 });
124
125 Fetcher fetcher(face, bind(&FetcherTestData::onData, this, _1, _2, _3, _4),
126 bind(&FetcherTestData::finish, this, _1, _2),
127 bind(&FetcherTestData::onComplete, this, _1),
128 bind(&FetcherTestData::onFail, this, _1), deviceName, Name("/fetchtest"), 0, 26,
129 time::seconds(5), Name());
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800130
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800131 BOOST_CHECK_EQUAL(fetcher.IsActive(), false);
132 fetcher.RestartPipeline();
133 BOOST_CHECK_EQUAL(fetcher.IsActive(), true);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800134
Yukai Tu35963e02016-10-24 13:48:01 -0700135 this->advanceClocks(time::milliseconds(50), 1000);
136 BOOST_CHECK_EQUAL(m_failed, true);
137 BOOST_CHECK_EQUAL(differentNames.size(), 1);
138 BOOST_CHECK_EQUAL(segmentNames.size(), 20);
139 BOOST_CHECK_EQUAL(recvData.size(), 20);
140 BOOST_CHECK_EQUAL(recvContent.size(), 20);
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800141
Yukai Tu35963e02016-10-24 13:48:01 -0700142 BOOST_CHECK_EQUAL("0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24",
143 join(recvData | boost::adaptors::transformed([] (int i) { return std::to_string(i); }), ", "));
144 BOOST_CHECK_EQUAL_COLLECTIONS(recvData.begin(), recvData.end(), recvContent.begin(), recvContent.end());
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800145
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800146 BOOST_CHECK_EQUAL(fetcher.IsActive(), false);
147 fetcher.RestartPipeline();
148 BOOST_CHECK_EQUAL(fetcher.IsActive(), true);
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800149
Yukai Tu35963e02016-10-24 13:48:01 -0700150 this->advanceClocks(time::milliseconds(100), 100);
151 BOOST_CHECK_EQUAL(m_done, false);
152 BOOST_CHECK_EQUAL(m_failed, true);
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800153 BOOST_CHECK_EQUAL(fetcher.IsActive(), false);
Yukai Tu35963e02016-10-24 13:48:01 -0700154
155 std::set<uint32_t> missing = {10, 11, 12, 13, 14, 25};
156 seqs.insert(missing.begin(), missing.end());
157
158 m_failed = false;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800159 fetcher.RestartPipeline();
160 BOOST_CHECK_EQUAL(fetcher.IsActive(), true);
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800161
Yukai Tu35963e02016-10-24 13:48:01 -0700162 this->advanceClocks(time::milliseconds(100), 100);
163 BOOST_CHECK_EQUAL(m_done, true);
164 BOOST_CHECK_EQUAL(m_failed, false);
165 BOOST_CHECK_EQUAL(segmentNames.size(), 27);
166 BOOST_CHECK_EQUAL(recvData.size(), 27);
167 BOOST_CHECK_EQUAL(recvContent.size(), 27);
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800168
Yukai Tu35963e02016-10-24 13:48:01 -0700169 BOOST_CHECK_EQUAL("0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26",
170 join(recvData | boost::adaptors::transformed([] (int i) { return std::to_string(i); }), ", "));
171 BOOST_CHECK_EQUAL_COLLECTIONS(recvData.begin(), recvData.end(), recvContent.begin(), recvContent.end());
Alexander Afanasyev650ba282013-01-20 20:14:06 -0800172
Yukai Tu35963e02016-10-24 13:48:01 -0700173 // TODO add tests that other callbacks got called
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800174}
175
Alexander Afanasyev21a166e2013-01-20 16:04:41 -0800176BOOST_AUTO_TEST_SUITE_END()
Yukai Tu35963e02016-10-24 13:48:01 -0700177
178} // namespace tests
179} // namespace chronoshare
180} // namespace ndn