blob: c96e57a1b444420322716472c2e5771cd484e2d3 [file] [log] [blame]
Junxiao Shi8c8d2182014-01-30 22:33:00 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7#include "fw/forwarder.hpp"
Junxiao Shid9ee45c2014-02-27 15:38:11 -07008#include "tests/face/dummy-face.hpp"
Junxiao Shif3c07812014-03-11 21:48:49 -07009#include "dummy-strategy.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070010
Junxiao Shid9ee45c2014-02-27 15:38:11 -070011#include "tests/test-common.hpp"
Junxiao Shif3c07812014-03-11 21:48:49 -070012#include "tests/core/limited-io.hpp"
Junxiao Shi8c8d2182014-01-30 22:33:00 -070013
14namespace nfd {
Junxiao Shid9ee45c2014-02-27 15:38:11 -070015namespace tests {
Junxiao Shi8c8d2182014-01-30 22:33:00 -070016
Junxiao Shid9ee45c2014-02-27 15:38:11 -070017BOOST_FIXTURE_TEST_SUITE(FwForwarder, BaseFixture)
Junxiao Shi8c8d2182014-01-30 22:33:00 -070018
Junxiao Shi8c8d2182014-01-30 22:33:00 -070019BOOST_AUTO_TEST_CASE(SimpleExchange)
20{
Junxiao Shic041ca32014-02-25 20:01:15 -070021 Forwarder forwarder;
22
Junxiao Shi8c8d2182014-01-30 22:33:00 -070023 Name nameA ("ndn:/A");
24 Name nameAB ("ndn:/A/B");
25 Name nameABC("ndn:/A/B/C");
Junxiao Shif3c07812014-03-11 21:48:49 -070026 shared_ptr<Interest> interestAB = makeInterest(nameAB);
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -070027 interestAB->setInterestLifetime(time::seconds(4));
Junxiao Shif3c07812014-03-11 21:48:49 -070028 shared_ptr<Data> dataABC = makeData(nameABC);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070029
Junxiao Shid9ee45c2014-02-27 15:38:11 -070030 shared_ptr<DummyFace> face1 = make_shared<DummyFace>();
31 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
32 face1->afterSend += bind(&boost::asio::io_service::stop, &g_io);
33 face2->afterSend += bind(&boost::asio::io_service::stop, &g_io);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070034 forwarder.addFace(face1);
35 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070036
Junxiao Shi8c8d2182014-01-30 22:33:00 -070037 Fib& fib = forwarder.getFib();
38 std::pair<shared_ptr<fib::Entry>, bool> fibInsertResult =
39 fib.insert(Name("ndn:/A"));
40 shared_ptr<fib::Entry> fibEntry = fibInsertResult.first;
41 fibEntry->addNextHop(face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070042
Junxiao Shib289cc12014-03-15 12:19:05 -070043 BOOST_CHECK_EQUAL(forwarder.getCounters().getInInterest (), 0);
44 BOOST_CHECK_EQUAL(forwarder.getCounters().getOutInterest(), 0);
Junxiao Shif3c07812014-03-11 21:48:49 -070045 face1->receiveInterest(*interestAB);
Junxiao Shid9ee45c2014-02-27 15:38:11 -070046 g_io.run();
47 g_io.reset();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070048 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
49 BOOST_CHECK(face2->m_sentInterests[0].getName().equals(nameAB));
Junxiao Shi06887ac2014-02-13 20:15:42 -070050 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
Junxiao Shib289cc12014-03-15 12:19:05 -070051 BOOST_CHECK_EQUAL(forwarder.getCounters().getInInterest (), 1);
52 BOOST_CHECK_EQUAL(forwarder.getCounters().getOutInterest(), 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070053
Junxiao Shib289cc12014-03-15 12:19:05 -070054 BOOST_CHECK_EQUAL(forwarder.getCounters().getInData (), 0);
55 BOOST_CHECK_EQUAL(forwarder.getCounters().getOutData(), 0);
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080056 face2->receiveData(*dataABC);
Junxiao Shid9ee45c2014-02-27 15:38:11 -070057 g_io.run();
58 g_io.reset();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070059 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
60 BOOST_CHECK(face1->m_sentDatas[0].getName().equals(nameABC));
Junxiao Shi06887ac2014-02-13 20:15:42 -070061 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
Junxiao Shib289cc12014-03-15 12:19:05 -070062 BOOST_CHECK_EQUAL(forwarder.getCounters().getInData (), 1);
63 BOOST_CHECK_EQUAL(forwarder.getCounters().getOutData(), 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070064}
65
Junxiao Shi9b27bd22014-02-26 20:29:58 -070066class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -070067{
68public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -070069 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -070070 {
71 }
72
73 virtual void
74 onDataUnsolicited(Face& inFace, const Data& data)
75 {
76 ++m_onDataUnsolicited_count;
77 }
78
79protected:
80 virtual void
Junxiao Shif3c07812014-03-11 21:48:49 -070081 dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f)
Junxiao Shi88884492014-02-15 15:57:43 -070082 {
83 ++m_dispatchToStrategy_count;
84 }
85
86public:
87 int m_dispatchToStrategy_count;
88 int m_onDataUnsolicited_count;
89};
90
Junxiao Shi9b27bd22014-02-26 20:29:58 -070091BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -070092{
Junxiao Shi9b27bd22014-02-26 20:29:58 -070093 ScopeLocalhostIncomingTestForwarder forwarder;
94 shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
95 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -070096 forwarder.addFace(face1);
97 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070098
Junxiao Shi88884492014-02-15 15:57:43 -070099 // local face, /localhost: OK
100 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700101 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800102 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi88884492014-02-15 15:57:43 -0700103 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700104
Junxiao Shi88884492014-02-15 15:57:43 -0700105 // non-local face, /localhost: violate
106 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700107 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800108 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi88884492014-02-15 15:57:43 -0700109 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700110
Junxiao Shi88884492014-02-15 15:57:43 -0700111 // local face, non-/localhost: OK
112 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700113 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800114 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi88884492014-02-15 15:57:43 -0700115 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700116
Junxiao Shi88884492014-02-15 15:57:43 -0700117 // non-local face, non-/localhost: OK
118 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700119 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800120 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi88884492014-02-15 15:57:43 -0700121 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700122
Junxiao Shi88884492014-02-15 15:57:43 -0700123 // local face, /localhost: OK
124 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700125 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800126 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi88884492014-02-15 15:57:43 -0700127 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
128
129 // non-local face, /localhost: OK
130 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700131 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800132 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi88884492014-02-15 15:57:43 -0700133 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700134
Junxiao Shi88884492014-02-15 15:57:43 -0700135 // local face, non-/localhost: OK
136 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700137 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800138 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi88884492014-02-15 15:57:43 -0700139 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
140
141 // non-local face, non-/localhost: OK
142 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700143 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800144 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi88884492014-02-15 15:57:43 -0700145 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
146}
147
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700148BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
149{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700150 Forwarder forwarder;
151 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
152 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
153 shared_ptr<Face> face3 = make_shared<DummyLocalFace>();
154 forwarder.addFace(face1);
155 forwarder.addFace(face2);
156 forwarder.addFace(face3);
157 Pit& pit = forwarder.getPit();
158
159 // local face, /localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700160 shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
161 shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
162 pitA1->insertOrUpdateInRecord(face3, *interestA1);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700163 face1->m_sentInterests.clear();
164 forwarder.onOutgoingInterest(pitA1, *face1);
165 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
166
167 // non-local face, /localhost: violate
Junxiao Shif3c07812014-03-11 21:48:49 -0700168 shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
169 shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
170 pitA2->insertOrUpdateInRecord(face3, *interestA2);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700171 face2->m_sentInterests.clear();
172 forwarder.onOutgoingInterest(pitA2, *face2);
173 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
174
175 // local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700176 shared_ptr<Interest> interestA3 = makeInterest("/A3");
177 shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
178 pitA3->insertOrUpdateInRecord(face3, *interestA3);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700179 face1->m_sentInterests.clear();
180 forwarder.onOutgoingInterest(pitA3, *face1);
181 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
182
183 // non-local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700184 shared_ptr<Interest> interestA4 = makeInterest("/A4");
185 shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
186 pitA4->insertOrUpdateInRecord(face3, *interestA4);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700187 face2->m_sentInterests.clear();
188 forwarder.onOutgoingInterest(pitA4, *face2);
189 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
190
191 // local face, /localhost: OK
192 face1->m_sentDatas.clear();
193 forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
194 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
195
196 // non-local face, /localhost: OK
197 face2->m_sentDatas.clear();
198 forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
199 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
200
201 // local face, non-/localhost: OK
202 face1->m_sentDatas.clear();
203 forwarder.onOutgoingData(Data("/B3"), *face1);
204 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
205
206 // non-local face, non-/localhost: OK
207 face2->m_sentDatas.clear();
208 forwarder.onOutgoingData(Data("/B4"), *face2);
209 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
210}
211
Junxiao Shi11bd9c22014-03-13 20:44:13 -0700212BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
213{
214 Forwarder forwarder;
215 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
216 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
217 shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
218 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
219 forwarder.addFace(face1);
220 forwarder.addFace(face2);
221 forwarder.addFace(face3);
222 forwarder.addFace(face4);
223 Pit& pit = forwarder.getPit();
224
225 // from local face, to local face: OK
226 shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
227 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
228 pit1->insertOrUpdateInRecord(face1, *interest1);
229 face3->m_sentInterests.clear();
230 forwarder.onOutgoingInterest(pit1, *face3);
231 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
232
233 // from non-local face, to local face: OK
234 shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
235 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
236 pit2->insertOrUpdateInRecord(face2, *interest2);
237 face3->m_sentInterests.clear();
238 forwarder.onOutgoingInterest(pit2, *face3);
239 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
240
241 // from local face, to non-local face: OK
242 shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
243 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
244 pit3->insertOrUpdateInRecord(face1, *interest3);
245 face4->m_sentInterests.clear();
246 forwarder.onOutgoingInterest(pit3, *face4);
247 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
248
249 // from non-local face, to non-local face: violate
250 shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
251 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
252 pit4->insertOrUpdateInRecord(face2, *interest4);
253 face4->m_sentInterests.clear();
254 forwarder.onOutgoingInterest(pit4, *face4);
255 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
256
257 // from local face and non-local face, to local face: OK
258 shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
259 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
260 pit5->insertOrUpdateInRecord(face1, *interest5);
261 pit5->insertOrUpdateInRecord(face2, *interest5);
262 face3->m_sentInterests.clear();
263 forwarder.onOutgoingInterest(pit5, *face3);
264 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
265
266 // from local face and non-local face, to non-local face: OK
267 shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
268 shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
269 pit6->insertOrUpdateInRecord(face1, *interest6);
270 pit6->insertOrUpdateInRecord(face2, *interest6);
271 face4->m_sentInterests.clear();
272 forwarder.onOutgoingInterest(pit6, *face4);
273 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
274}
275
Junxiao Shif3c07812014-03-11 21:48:49 -0700276BOOST_AUTO_TEST_CASE(StrategyDispatch)
277{
278 LimitedIo limitedIo;
279 Forwarder forwarder;
280 shared_ptr<Face> face1 = make_shared<DummyFace>();
281 shared_ptr<Face> face2 = make_shared<DummyFace>();
282 forwarder.addFace(face1);
283 forwarder.addFace(face2);
284
285 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
286 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
287 boost::ref(forwarder), "ndn:/strategyP");
288 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
289 boost::ref(forwarder), "ndn:/strategyQ");
290 strategyChoice.install(strategyP);
291 strategyChoice.install(strategyQ);
292 strategyChoice.insert("ndn:/" , strategyP->getName());
293 strategyChoice.insert("ndn:/B", strategyQ->getName());
294
295 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
296 strategyP->m_afterReceiveInterest_count = 0;
297 strategyP->m_interestOutFace = face2;
298 forwarder.onInterest(*face1, *interest1);
299 BOOST_CHECK_EQUAL(strategyP->m_afterReceiveInterest_count, 1);
300
301 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
302 strategyQ->m_afterReceiveInterest_count = 0;
303 strategyQ->m_interestOutFace = face2;
304 forwarder.onInterest(*face1, *interest2);
305 BOOST_CHECK_EQUAL(strategyQ->m_afterReceiveInterest_count, 1);
306
307 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
308
309 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
310 strategyP->m_beforeSatisfyPendingInterest_count = 0;
311 forwarder.onData(*face2, *data1);
312 BOOST_CHECK_EQUAL(strategyP->m_beforeSatisfyPendingInterest_count, 1);
313
314 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
315 strategyQ->m_beforeSatisfyPendingInterest_count = 0;
316 forwarder.onData(*face2, *data2);
317 BOOST_CHECK_EQUAL(strategyQ->m_beforeSatisfyPendingInterest_count, 1);
318
319 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700320 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shif3c07812014-03-11 21:48:49 -0700321 forwarder.onInterest(*face1, *interest3);
322 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700323 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shif3c07812014-03-11 21:48:49 -0700324 forwarder.onInterest(*face1, *interest4);
325
326 strategyP->m_beforeExpirePendingInterest_count = 0;
327 strategyQ->m_beforeExpirePendingInterest_count = 0;
328 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
329 BOOST_CHECK_EQUAL(strategyP->m_beforeExpirePendingInterest_count, 1);
330 BOOST_CHECK_EQUAL(strategyQ->m_beforeExpirePendingInterest_count, 0);
331}
332
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700333BOOST_AUTO_TEST_SUITE_END()
334
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700335} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700336} // namespace nfd