blob: cba3d2c5e267478eb43d5e96caf35a4ecd97cad9 [file] [log] [blame]
Yingdi Yu6ff31932015-03-23 13:30:07 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Alexander Afanasyevbe998ac2017-05-06 13:11:42 -07003 * Copyright (c) 2014-2017, Regents of the University of California
Yingdi Yu6ff31932015-03-23 13:30:07 -07004 *
Alexander Afanasyevbe998ac2017-05-06 13:11:42 -07005 * This file is part of NDN DeLorean, An Authentication System for Data Archives in
6 * Named Data Networking. See AUTHORS.md for complete list of NDN DeLorean authors
7 * and contributors.
Yingdi Yu6ff31932015-03-23 13:30:07 -07008 *
Alexander Afanasyevbe998ac2017-05-06 13:11:42 -07009 * NDN DeLorean is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
Yingdi Yu6ff31932015-03-23 13:30:07 -070013 *
Alexander Afanasyevbe998ac2017-05-06 13:11:42 -070014 * NDN DeLorean is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
16 * PARTICULAR PURPOSE. See the GNU General Public License for more details.
Yingdi Yu6ff31932015-03-23 13:30:07 -070017 *
Alexander Afanasyevbe998ac2017-05-06 13:11:42 -070018 * You should have received a copy of the GNU General Public License along with NDN
19 * DeLorean, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
Yingdi Yu6ff31932015-03-23 13:30:07 -070020 */
21
22#include "logger.hpp"
23#include "identity-fixture.hpp"
24#include "db-fixture.hpp"
25#include <ndn-cxx/util/dummy-client-face.hpp>
26#include <ndn-cxx/util/io.hpp>
27
28#include "boost-test.hpp"
29
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -070030namespace ndn {
31namespace delorean {
Yingdi Yu6ff31932015-03-23 13:30:07 -070032namespace tests {
33
34class LoggerFixture : public IdentityFixture
35 , public DbFixture
36{
37public:
38 LoggerFixture()
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -070039 : face1(io, {true, true})
40 , face2(io, {true, true})
Yingdi Yu6ff31932015-03-23 13:30:07 -070041 , readInterestOffset1(0)
42 , readDataOffset1(0)
43 , readInterestOffset2(0)
44 , readDataOffset2(0)
45 {
46 }
47
48 ~LoggerFixture()
49 {
50 }
51
52 bool
53 passPacket()
54 {
55 bool hasPassed = false;
56
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -070057 checkFace(face1.sentInterests, readInterestOffset1, face2, hasPassed);
58 checkFace(face1.sentData, readDataOffset1, face2, hasPassed);
59 checkFace(face2.sentInterests, readInterestOffset2, face1, hasPassed);
60 checkFace(face2.sentData, readDataOffset2, face1, hasPassed);
Yingdi Yu6ff31932015-03-23 13:30:07 -070061
62 return hasPassed;
63 }
64
65 template<typename Packet>
66 void
67 checkFace(std::vector<Packet>& receivedPackets,
68 size_t& readPacketOffset,
69 ndn::util::DummyClientFace& receiver,
70 bool& hasPassed)
71 {
72 while (receivedPackets.size() > readPacketOffset) {
73 receiver.receive(receivedPackets[readPacketOffset]);
74 readPacketOffset++;
75 hasPassed = true;
76 }
77 }
78
79 void
80 clear()
81 {
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -070082 face1.sentData.clear();
83 face1.sentInterests.clear();
84 face2.sentData.clear();
85 face2.sentInterests.clear();
Yingdi Yu6ff31932015-03-23 13:30:07 -070086
87 readInterestOffset1 = 0;
88 readDataOffset1 = 0;
89 readInterestOffset2 = 0;
90 readDataOffset2 = 0;
91 }
92
93public:
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -070094 ndn::util::DummyClientFace face1;
95 ndn::util::DummyClientFace face2;
Yingdi Yu6ff31932015-03-23 13:30:07 -070096
97 size_t readInterestOffset1;
98 size_t readDataOffset1;
99 size_t readInterestOffset2;
100 size_t readDataOffset2;
101};
102
103BOOST_FIXTURE_TEST_SUITE(TestLogger, LoggerFixture)
104
105const std::string CONFIG =
106 "logger-name /test/logger \n"
107 "policy \n"
108 "{ \n"
109 " rule \n"
110 " { \n"
111 " id \"Simple Rule\" \n"
112 " for data \n"
113 " checker \n"
114 " { \n"
115 " type customized \n"
116 " sig-type rsa-sha256 \n"
117 " key-locator \n"
118 " { \n"
119 " type name \n"
120 " hyper-relation \n"
121 " { \n"
122 " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
123 " k-expand \\\\1\\\\2 \n"
124 " h-relation is-strict-prefix-of \n"
125 " p-regex ^(<>*)$ \n"
126 " p-expand \\\\1 \n"
127 " } \n"
128 " } \n"
129 " } \n"
130 " } \n"
131 "} \n"
132 "validator \n"
133 "{ \n"
134 " rule \n"
135 " { \n"
136 " id \"Request Rule\" \n"
137 " for interest \n"
138 " filter \n"
139 " { \n"
140 " type name \n"
141 " name /test/logger/log \n"
142 " relation is-strict-prefix-of \n"
143 " } \n"
144 " checker \n"
145 " { \n"
146 " type customized \n"
147 " sig-type rsa-sha256 \n"
148 " key-locator \n"
149 " { \n"
150 " type name \n"
151 " regex ^[^<KEY>]*<KEY><>*<><ID-CERT>$ \n"
152 " } \n"
153 " } \n"
154 " } \n"
155 " rule \n"
156 " { \n"
157 " id \"Simple Rule\" \n"
158 " for data \n"
159 " checker \n"
160 " { \n"
161 " type customized \n"
162 " sig-type rsa-sha256 \n"
163 " key-locator \n"
164 " { \n"
165 " type name \n"
166 " hyper-relation \n"
167 " { \n"
168 " k-regex ^([^<KEY>]*)<KEY>(<>*)<><ID-CERT>$ \n"
169 " k-expand \\\\1\\\\2 \n"
170 " h-relation is-strict-prefix-of \n"
171 " p-regex ^(<>*)$ \n"
172 " p-expand \\\\1 \n"
173 " } \n"
174 " } \n"
175 " } \n"
176 " } \n"
177 " trust-anchor \n"
178 " { \n"
179 " type file \n"
180 " file-name \"trust-anchor.cert\" \n"
181 " } \n"
182 "} \n";
183
184BOOST_AUTO_TEST_CASE(Basic)
185{
186 namespace fs = boost::filesystem;
187
188 fs::create_directory(fs::path(TEST_LOGGER_PATH));
189
190 fs::path configPath = fs::path(TEST_LOGGER_PATH) / "logger-test.conf";
191 std::ofstream os(configPath.c_str());
192 os << CONFIG;
193 os.close();
194
195 Name root("/ndn");
196 addIdentity(root);
197 auto rootCert = m_keyChain.getCertificate(m_keyChain.getDefaultCertificateNameForIdentity(root));
198 fs::path certPath = fs::path(TEST_LOGGER_PATH) / "trust-anchor.cert";
199 ndn::io::save(*rootCert, certPath.string());
200
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700201 Logger logger(face1, configPath.string());
Yingdi Yu6ff31932015-03-23 13:30:07 -0700202
203 BOOST_CHECK_EQUAL(logger.getLoggerName(), Name("/test/logger"));
204 BOOST_CHECK_EQUAL(logger.getTreePrefix(), Name("/test/logger/tree"));
205 BOOST_CHECK_EQUAL(logger.getLeafPrefix(), Name("/test/logger/leaf"));
206 BOOST_CHECK_EQUAL(logger.getLogPrefix(), Name("/test/logger/log"));
207
208 advanceClocks(time::milliseconds(2), 100);
209
210 Timestamp rootTs = time::toUnixTimestamp(time::system_clock::now()).count() / 1000;
211 NonNegativeInteger rootSeqNo = logger.addSelfSignedCert(*rootCert, rootTs);
212 BOOST_CHECK_EQUAL(rootSeqNo, 0);
213
214 Name leafInterestName("/test/logger/leaf");
215 leafInterestName.appendNumber(0);
216 auto leafInterest = make_shared<Interest>(leafInterestName);
217
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700218 face1.receive(*leafInterest);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700219 advanceClocks(time::milliseconds(2), 100);
220
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700221 BOOST_CHECK_EQUAL(face1.sentData.size(), 1);
222 BOOST_CHECK(leafInterestName.isPrefixOf(face1.sentData[0].getName()));
Yingdi Yu6ff31932015-03-23 13:30:07 -0700223
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700224 face1.sentData.clear();
Yingdi Yu6ff31932015-03-23 13:30:07 -0700225
226 Name treeInterestName("/test/logger/tree");
227 treeInterestName.appendNumber(0);
228 treeInterestName.appendNumber(0);
229 auto treeInterest = make_shared<Interest>(treeInterestName);
230
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700231 face1.receive(*treeInterest);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700232 advanceClocks(time::milliseconds(2), 100);
233
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700234 BOOST_CHECK_EQUAL(face1.sentData.size(), 1);
235 BOOST_CHECK(treeInterestName.isPrefixOf(face1.sentData[0].getName()));
Yingdi Yu6ff31932015-03-23 13:30:07 -0700236
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700237 face1.sentData.clear();
Yingdi Yu6ff31932015-03-23 13:30:07 -0700238
239 Name tld("/ndn/tld");
240 Name tldKeyName = m_keyChain.generateRsaKeyPair(tld);
241 std::vector<ndn::CertificateSubjectDescription> subjectDescription;
242 auto tldCert =
243 m_keyChain.prepareUnsignedIdentityCertificate(tldKeyName, root,
244 time::system_clock::now(),
245 time::system_clock::now() + time::days(1),
246 subjectDescription);
247 m_keyChain.signByIdentity(*tldCert, root);
248 m_keyChain.addCertificate(*tldCert);
249
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700250 face2.setInterestFilter(tldCert->getName().getPrefix(-1),
251 [&] (const ndn::InterestFilter&, const Interest&) { face2.put(*tldCert); },
Yingdi Yu6ff31932015-03-23 13:30:07 -0700252 ndn::RegisterPrefixSuccessCallback(),
253 [] (const Name&, const std::string&) {});
254 advanceClocks(time::milliseconds(2), 100);
255 clear();
256
257 Name logInterestName("/test/logger/log");
258 logInterestName.append(tldCert->getFullName().wireEncode());
259 logInterestName.appendNumber(0);
260 auto logInterest = make_shared<Interest>(logInterestName);
261 m_keyChain.sign(*logInterest, tldCert->getName());
262
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700263 face1.receive(*logInterest);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700264 do {
265 advanceClocks(time::milliseconds(2), 100);
266 } while (passPacket());
267 clear();
268
269 BOOST_CHECK_EQUAL(logger.getDb().getMaxLeafSeq(), 2);
270 auto leafResult1 = logger.getDb().getLeaf(1);
271 BOOST_CHECK(leafResult1.first != nullptr);
272 BOOST_CHECK(leafResult1.second != nullptr);
273
274
275
276 Name leafInterestName2("/test/logger/leaf");
277 leafInterestName2.appendNumber(1);
278 auto leafInterest2 = make_shared<Interest>(leafInterestName2);
279
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700280 face1.receive(*leafInterest2);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700281 advanceClocks(time::milliseconds(2), 100);
282
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700283 BOOST_CHECK_EQUAL(face1.sentData.size(), 1);
284 BOOST_CHECK(leafInterestName2.isPrefixOf(face1.sentData[0].getName()));
Yingdi Yu6ff31932015-03-23 13:30:07 -0700285 clear();
286
287
288
289 Name treeInterestName2("/test/logger/tree");
290 treeInterestName2.appendNumber(1);
291 treeInterestName2.appendNumber(0);
292 auto treeInterest2 = make_shared<Interest>(treeInterestName2);
293
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700294 face1.receive(*treeInterest2);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700295 advanceClocks(time::milliseconds(2), 100);
296
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700297 BOOST_CHECK_EQUAL(face1.sentData.size(), 1);
298 BOOST_CHECK(treeInterestName2.isPrefixOf(face1.sentData[0].getName()));
Yingdi Yu6ff31932015-03-23 13:30:07 -0700299 clear();
300
301
302 auto data = make_shared<Data>(Name("/ndn/tld/data"));
303 m_keyChain.sign(*data, tldCert->getName());
304
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700305 face2.setInterestFilter(data->getName(),
306 [&] (const ndn::InterestFilter&, const Interest&) { face2.put(*data); },
Yingdi Yu6ff31932015-03-23 13:30:07 -0700307 ndn::RegisterPrefixSuccessCallback(),
308 [] (const Name&, const std::string&) {});
309 advanceClocks(time::milliseconds(2), 100);
310 clear();
311
312 Name logInterestName2("/test/logger/log");
313 logInterestName2.append(data->getFullName().wireEncode());
314 logInterestName2.appendNumber(1);
315 auto logInterest2 = make_shared<Interest>(logInterestName2);
316 m_keyChain.sign(*logInterest2, tldCert->getName());
317
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700318 face1.receive(*logInterest2);
Yingdi Yu6ff31932015-03-23 13:30:07 -0700319 do {
320 advanceClocks(time::milliseconds(2), 100);
321 } while (passPacket());
322 clear();
323
324 BOOST_CHECK_EQUAL(logger.getDb().getMaxLeafSeq(), 3);
325 auto leafResult2 = logger.getDb().getLeaf(2);
326 BOOST_CHECK(leafResult2.first != nullptr);
327 BOOST_CHECK(leafResult2.second == nullptr);
328
329
330 fs::remove_all(fs::path(TEST_LOGGER_PATH));
331}
332
333BOOST_AUTO_TEST_SUITE_END()
334
335} // namespace tests
Alexander Afanasyev49e2e4c2017-05-06 13:42:57 -0700336} // namespace delorean
337} // namespace ndn