blob: 266bcf59646b1996c4ee444b16cf16e17b95080d [file] [log] [blame]
Chavoosh Ghasemibb2d2802019-03-26 16:07:58 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2016-2019, Regents of the University of California,
4 * Colorado State University,
5 * University Pierre & Marie Curie, Sorbonne University.
6 *
7 * This file is part of ndn-tools (Named Data Networking Essential Tools).
8 * See AUTHORS.md for complete list of ndn-tools authors and contributors.
9 *
10 * ndn-tools is free software: you can redistribute it and/or modify it under the terms
11 * of the GNU General Public License as published by the Free Software Foundation,
12 * either version 3 of the License, or (at your option) any later version.
13 *
14 * ndn-tools is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
15 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * ndn-tools, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
20 *
21 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
22 *
23 * @author Chavoosh Ghasemi
24 */
25
26#include "tools/chunks/catchunks/discover-version.hpp"
27
28#include "tests/test-common.hpp"
29#include "tests/identity-management-fixture.hpp"
30
31#include <ndn-cxx/metadata-object.hpp>
32#include <ndn-cxx/util/dummy-client-face.hpp>
33
34namespace ndn {
35namespace chunks {
36namespace tests {
37
38using namespace ndn::tests;
39
40class DiscoverVersionFixture : public UnitTestTimeFixture,
41 public IdentityManagementFixture
42{
43public:
44 DiscoverVersionFixture()
45 : face(io)
46 , name("/ndn/chunks/test")
47 , isDiscoveryFinished(false)
48 , version(1449227841747)
49 {
50 opt.interestLifetime = ndn::DEFAULT_INTEREST_LIFETIME;
51 opt.maxRetriesOnTimeoutOrNack = 15;
52 opt.isVerbose = false;
53 }
54
55 void
56 run(const Name& prefix)
57 {
58 BOOST_REQUIRE(!prefix.empty());
59 discover = make_unique<DiscoverVersion>(prefix, face, opt);
60 discover->onDiscoverySuccess.connect([this] (const Name& versionedName) {
61 isDiscoveryFinished = true;
62 BOOST_REQUIRE(!versionedName.empty() && versionedName[-1].isVersion());
63 discoveredVersion = versionedName[-1].toVersion();
64 });
65 discover->onDiscoveryFailure.connect([this] (const std::string& reason) {
66 isDiscoveryFinished = true;
67 });
68
69 discover->run();
70 advanceClocks(io, time::nanoseconds(1));
71 }
72
73protected:
74 boost::asio::io_service io;
75 util::DummyClientFace face;
76 Name name;
77 unique_ptr<DiscoverVersion> discover;
78 optional<uint64_t> discoveredVersion;
79 bool isDiscoveryFinished;
80 uint64_t version;
81 Options opt;
82};
83
84BOOST_AUTO_TEST_SUITE(Chunks)
85BOOST_FIXTURE_TEST_SUITE(TestDiscoverVersion, DiscoverVersionFixture)
86
87BOOST_AUTO_TEST_CASE(VersionNumberIsProvided)
88{
89 run(Name(name).appendVersion(version));
90
91 // no version discovery interest is expressed
92 BOOST_CHECK_EQUAL(face.sentInterests.size(), 0);
93
94 BOOST_CHECK_EQUAL(isDiscoveryFinished, true);
95 BOOST_CHECK_EQUAL(discoveredVersion.value(), version);
96}
97
98BOOST_AUTO_TEST_CASE(DiscoverySuccess)
99{
100 // express a discovery Interest to learn Data version
101 run(name);
102
103 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
104
105 Interest discoveryInterest = MetadataObject::makeDiscoveryInterest(name);
106 auto lastInterest = face.sentInterests.back();
107 BOOST_CHECK_EQUAL(lastInterest.getName(), discoveryInterest.getName());
108
109 // Send back a metadata packet with a valid versioned name
110 MetadataObject mobject;
111 mobject.setVersionedName(Name(name).appendVersion(version));
112 face.receive(mobject.makeData(lastInterest.getName(), m_keyChain));
113 advanceClocks(io, time::nanoseconds(1));
114
115 BOOST_CHECK(isDiscoveryFinished);
116 BOOST_CHECK_EQUAL(discoveredVersion.value(), version);
117}
118
119BOOST_AUTO_TEST_CASE(InvalidDiscoveredVersionedName)
120{
121 // issue a discovery Interest to learn Data version
122 run(name);
123
124 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
125
126 // Send back a metadata packet with an invalid versioned name
127 MetadataObject mobject;
128 mobject.setVersionedName(name);
129 face.receive(mobject.makeData(face.sentInterests.back().getName(), m_keyChain));
130
131 // finish discovery process without a resolved version number
132 BOOST_CHECK(isDiscoveryFinished);
133 BOOST_CHECK(!discoveredVersion.has_value());
134}
135
136BOOST_AUTO_TEST_CASE(InvalidMetadataPacket)
137{
138 // issue a discovery Interest to learn Data version
139 run(name);
140
141 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
142
143 // Send back an invalid metadata packet
144 Data data(face.sentInterests.back().getName());
145 data.setContentType(tlv::ContentType_Key);
146 face.receive(signData(data));
147
148 // finish discovery process without a resolved version number
149 BOOST_CHECK(isDiscoveryFinished);
150 BOOST_CHECK(!discoveredVersion.has_value());
151}
152
153BOOST_AUTO_TEST_CASE(Timeout1)
154{
155 // issue a discovery Interest to learn Data version
156 run(name);
157
158 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
159
160 // timeout discovery Interests
161 for (int retries = 0; retries < opt.maxRetriesOnTimeoutOrNack; ++retries) {
162 advanceClocks(io, opt.interestLifetime);
163
164 BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
165 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), retries + 2);
166 }
167
168 // timeout the last sent Interest
169 advanceClocks(io, opt.interestLifetime);
170
171 // finish discovery process without a resolved version number
172 BOOST_CHECK(isDiscoveryFinished);
173 BOOST_CHECK(!discoveredVersion.has_value());
174}
175
176BOOST_AUTO_TEST_CASE(Timeout2)
177{
178 // issue a discovery Interest to learn Data version
179 run(name);
180
181 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), 1);
182
183 // timeout discovery Interests
184 for (int retries = 0; retries < opt.maxRetriesOnTimeoutOrNack; ++retries) {
185 advanceClocks(io, opt.interestLifetime);
186
187 BOOST_CHECK_EQUAL(isDiscoveryFinished, false);
188 BOOST_REQUIRE_EQUAL(face.sentInterests.size(), retries + 2);
189 }
190
191 // satisfy the last Interest with a valid metadata packet
192 MetadataObject mobject;
193 mobject.setVersionedName(Name(name).appendVersion(version));
194 face.receive(mobject.makeData(face.sentInterests.back().getName(), m_keyChain));
195 advanceClocks(io, time::nanoseconds(1));
196
197 BOOST_CHECK(isDiscoveryFinished);
198 BOOST_CHECK_EQUAL(discoveredVersion.value(), version);
199}
200
201BOOST_AUTO_TEST_SUITE_END() // TestDiscoverVersion
202BOOST_AUTO_TEST_SUITE_END() // Chunks
203
204} // namespace tests
205} // namespace chunks
206} // namespace ndn