blob: 53cb145ba8fbfcd39ac8a43a3659ad02471ed5e0 [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();
Junxiao Shi6e694322014-04-03 10:27:13 -070038 shared_ptr<fib::Entry> fibEntry = fib.insert(Name("ndn:/A")).first;
Junxiao Shi8c8d2182014-01-30 22:33:00 -070039 fibEntry->addNextHop(face2, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -070040
Junxiao Shi6e694322014-04-03 10:27:13 -070041 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 0);
42 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 0);
Junxiao Shif3c07812014-03-11 21:48:49 -070043 face1->receiveInterest(*interestAB);
Junxiao Shid9ee45c2014-02-27 15:38:11 -070044 g_io.run();
45 g_io.reset();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070046 BOOST_REQUIRE_EQUAL(face2->m_sentInterests.size(), 1);
47 BOOST_CHECK(face2->m_sentInterests[0].getName().equals(nameAB));
Junxiao Shi06887ac2014-02-13 20:15:42 -070048 BOOST_CHECK_EQUAL(face2->m_sentInterests[0].getIncomingFaceId(), face1->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070049 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInInterests (), 1);
50 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutInterests(), 1);
Junxiao Shic041ca32014-02-25 20:01:15 -070051
Junxiao Shi6e694322014-04-03 10:27:13 -070052 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 0);
53 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 0);
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -080054 face2->receiveData(*dataABC);
Junxiao Shid9ee45c2014-02-27 15:38:11 -070055 g_io.run();
56 g_io.reset();
Junxiao Shi8c8d2182014-01-30 22:33:00 -070057 BOOST_REQUIRE_EQUAL(face1->m_sentDatas.size(), 1);
58 BOOST_CHECK(face1->m_sentDatas[0].getName().equals(nameABC));
Junxiao Shi06887ac2014-02-13 20:15:42 -070059 BOOST_CHECK_EQUAL(face1->m_sentDatas[0].getIncomingFaceId(), face2->getId());
Junxiao Shi6e694322014-04-03 10:27:13 -070060 BOOST_CHECK_EQUAL(forwarder.getCounters().getNInDatas (), 1);
61 BOOST_CHECK_EQUAL(forwarder.getCounters().getNOutDatas(), 1);
Junxiao Shi8c8d2182014-01-30 22:33:00 -070062}
63
Junxiao Shi9b27bd22014-02-26 20:29:58 -070064class ScopeLocalhostIncomingTestForwarder : public Forwarder
Junxiao Shi88884492014-02-15 15:57:43 -070065{
66public:
Junxiao Shi9b27bd22014-02-26 20:29:58 -070067 ScopeLocalhostIncomingTestForwarder()
Junxiao Shi88884492014-02-15 15:57:43 -070068 {
69 }
70
71 virtual void
72 onDataUnsolicited(Face& inFace, const Data& data)
73 {
74 ++m_onDataUnsolicited_count;
75 }
76
77protected:
78 virtual void
Junxiao Shif3c07812014-03-11 21:48:49 -070079 dispatchToStrategy(shared_ptr<pit::Entry> pitEntry, function<void(fw::Strategy*)> f)
Junxiao Shi88884492014-02-15 15:57:43 -070080 {
81 ++m_dispatchToStrategy_count;
82 }
83
84public:
85 int m_dispatchToStrategy_count;
86 int m_onDataUnsolicited_count;
87};
88
Junxiao Shi9b27bd22014-02-26 20:29:58 -070089BOOST_AUTO_TEST_CASE(ScopeLocalhostIncoming)
Junxiao Shi88884492014-02-15 15:57:43 -070090{
Junxiao Shi9b27bd22014-02-26 20:29:58 -070091 ScopeLocalhostIncomingTestForwarder forwarder;
92 shared_ptr<Face> face1 = make_shared<DummyLocalFace>();
93 shared_ptr<Face> face2 = make_shared<DummyFace>();
Junxiao Shi88884492014-02-15 15:57:43 -070094 forwarder.addFace(face1);
95 forwarder.addFace(face2);
Junxiao Shic041ca32014-02-25 20:01:15 -070096
Junxiao Shi88884492014-02-15 15:57:43 -070097 // local face, /localhost: OK
98 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -070099 shared_ptr<Interest> i1 = makeInterest("/localhost/A1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800100 forwarder.onIncomingInterest(*face1, *i1);
Junxiao Shi88884492014-02-15 15:57:43 -0700101 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700102
Junxiao Shi88884492014-02-15 15:57:43 -0700103 // non-local face, /localhost: violate
104 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700105 shared_ptr<Interest> i2 = makeInterest("/localhost/A2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800106 forwarder.onIncomingInterest(*face2, *i2);
Junxiao Shi88884492014-02-15 15:57:43 -0700107 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700108
Junxiao Shi88884492014-02-15 15:57:43 -0700109 // local face, non-/localhost: OK
110 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700111 shared_ptr<Interest> i3 = makeInterest("/A3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800112 forwarder.onIncomingInterest(*face1, *i3);
Junxiao Shi88884492014-02-15 15:57:43 -0700113 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700114
Junxiao Shi88884492014-02-15 15:57:43 -0700115 // non-local face, non-/localhost: OK
116 forwarder.m_dispatchToStrategy_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700117 shared_ptr<Interest> i4 = makeInterest("/A4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800118 forwarder.onIncomingInterest(*face2, *i4);
Junxiao Shi88884492014-02-15 15:57:43 -0700119 BOOST_CHECK_EQUAL(forwarder.m_dispatchToStrategy_count, 1);
Junxiao Shic041ca32014-02-25 20:01:15 -0700120
Junxiao Shi88884492014-02-15 15:57:43 -0700121 // local face, /localhost: OK
122 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700123 shared_ptr<Data> d1 = makeData("/localhost/B1");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800124 forwarder.onIncomingData(*face1, *d1);
Junxiao Shi88884492014-02-15 15:57:43 -0700125 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
126
127 // non-local face, /localhost: OK
128 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700129 shared_ptr<Data> d2 = makeData("/localhost/B2");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800130 forwarder.onIncomingData(*face2, *d2);
Junxiao Shi88884492014-02-15 15:57:43 -0700131 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 0);
Junxiao Shic041ca32014-02-25 20:01:15 -0700132
Junxiao Shi88884492014-02-15 15:57:43 -0700133 // local face, non-/localhost: OK
134 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700135 shared_ptr<Data> d3 = makeData("/B3");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800136 forwarder.onIncomingData(*face1, *d3);
Junxiao Shi88884492014-02-15 15:57:43 -0700137 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
138
139 // non-local face, non-/localhost: OK
140 forwarder.m_onDataUnsolicited_count = 0;
Junxiao Shif3c07812014-03-11 21:48:49 -0700141 shared_ptr<Data> d4 = makeData("/B4");
Ilya Moiseenko76cf77a2014-03-05 14:35:51 -0800142 forwarder.onIncomingData(*face2, *d4);
Junxiao Shi88884492014-02-15 15:57:43 -0700143 BOOST_CHECK_EQUAL(forwarder.m_onDataUnsolicited_count, 1);
144}
145
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700146BOOST_AUTO_TEST_CASE(ScopeLocalhostOutgoing)
147{
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700148 Forwarder forwarder;
149 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
150 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
151 shared_ptr<Face> face3 = make_shared<DummyLocalFace>();
152 forwarder.addFace(face1);
153 forwarder.addFace(face2);
154 forwarder.addFace(face3);
155 Pit& pit = forwarder.getPit();
156
157 // local face, /localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700158 shared_ptr<Interest> interestA1 = makeInterest("/localhost/A1");
159 shared_ptr<pit::Entry> pitA1 = pit.insert(*interestA1).first;
160 pitA1->insertOrUpdateInRecord(face3, *interestA1);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700161 face1->m_sentInterests.clear();
162 forwarder.onOutgoingInterest(pitA1, *face1);
163 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
164
165 // non-local face, /localhost: violate
Junxiao Shif3c07812014-03-11 21:48:49 -0700166 shared_ptr<Interest> interestA2 = makeInterest("/localhost/A2");
167 shared_ptr<pit::Entry> pitA2 = pit.insert(*interestA2).first;
168 pitA2->insertOrUpdateInRecord(face3, *interestA2);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700169 face2->m_sentInterests.clear();
170 forwarder.onOutgoingInterest(pitA2, *face2);
171 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 0);
172
173 // local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700174 shared_ptr<Interest> interestA3 = makeInterest("/A3");
175 shared_ptr<pit::Entry> pitA3 = pit.insert(*interestA3).first;
176 pitA3->insertOrUpdateInRecord(face3, *interestA3);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700177 face1->m_sentInterests.clear();
178 forwarder.onOutgoingInterest(pitA3, *face1);
179 BOOST_CHECK_EQUAL(face1->m_sentInterests.size(), 1);
180
181 // non-local face, non-/localhost: OK
Junxiao Shif3c07812014-03-11 21:48:49 -0700182 shared_ptr<Interest> interestA4 = makeInterest("/A4");
183 shared_ptr<pit::Entry> pitA4 = pit.insert(*interestA4).first;
184 pitA4->insertOrUpdateInRecord(face3, *interestA4);
Junxiao Shi9b27bd22014-02-26 20:29:58 -0700185 face2->m_sentInterests.clear();
186 forwarder.onOutgoingInterest(pitA4, *face2);
187 BOOST_CHECK_EQUAL(face2->m_sentInterests.size(), 1);
188
189 // local face, /localhost: OK
190 face1->m_sentDatas.clear();
191 forwarder.onOutgoingData(Data("/localhost/B1"), *face1);
192 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
193
194 // non-local face, /localhost: OK
195 face2->m_sentDatas.clear();
196 forwarder.onOutgoingData(Data("/localhost/B2"), *face2);
197 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 0);
198
199 // local face, non-/localhost: OK
200 face1->m_sentDatas.clear();
201 forwarder.onOutgoingData(Data("/B3"), *face1);
202 BOOST_CHECK_EQUAL(face1->m_sentDatas.size(), 1);
203
204 // non-local face, non-/localhost: OK
205 face2->m_sentDatas.clear();
206 forwarder.onOutgoingData(Data("/B4"), *face2);
207 BOOST_CHECK_EQUAL(face2->m_sentDatas.size(), 1);
208}
209
Junxiao Shi11bd9c22014-03-13 20:44:13 -0700210BOOST_AUTO_TEST_CASE(ScopeLocalhopOutgoing)
211{
212 Forwarder forwarder;
213 shared_ptr<DummyLocalFace> face1 = make_shared<DummyLocalFace>();
214 shared_ptr<DummyFace> face2 = make_shared<DummyFace>();
215 shared_ptr<DummyLocalFace> face3 = make_shared<DummyLocalFace>();
216 shared_ptr<DummyFace> face4 = make_shared<DummyFace>();
217 forwarder.addFace(face1);
218 forwarder.addFace(face2);
219 forwarder.addFace(face3);
220 forwarder.addFace(face4);
221 Pit& pit = forwarder.getPit();
222
223 // from local face, to local face: OK
224 shared_ptr<Interest> interest1 = makeInterest("/localhop/1");
225 shared_ptr<pit::Entry> pit1 = pit.insert(*interest1).first;
226 pit1->insertOrUpdateInRecord(face1, *interest1);
227 face3->m_sentInterests.clear();
228 forwarder.onOutgoingInterest(pit1, *face3);
229 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
230
231 // from non-local face, to local face: OK
232 shared_ptr<Interest> interest2 = makeInterest("/localhop/2");
233 shared_ptr<pit::Entry> pit2 = pit.insert(*interest2).first;
234 pit2->insertOrUpdateInRecord(face2, *interest2);
235 face3->m_sentInterests.clear();
236 forwarder.onOutgoingInterest(pit2, *face3);
237 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
238
239 // from local face, to non-local face: OK
240 shared_ptr<Interest> interest3 = makeInterest("/localhop/3");
241 shared_ptr<pit::Entry> pit3 = pit.insert(*interest3).first;
242 pit3->insertOrUpdateInRecord(face1, *interest3);
243 face4->m_sentInterests.clear();
244 forwarder.onOutgoingInterest(pit3, *face4);
245 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
246
247 // from non-local face, to non-local face: violate
248 shared_ptr<Interest> interest4 = makeInterest("/localhop/4");
249 shared_ptr<pit::Entry> pit4 = pit.insert(*interest4).first;
250 pit4->insertOrUpdateInRecord(face2, *interest4);
251 face4->m_sentInterests.clear();
252 forwarder.onOutgoingInterest(pit4, *face4);
253 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 0);
254
255 // from local face and non-local face, to local face: OK
256 shared_ptr<Interest> interest5 = makeInterest("/localhop/5");
257 shared_ptr<pit::Entry> pit5 = pit.insert(*interest5).first;
258 pit5->insertOrUpdateInRecord(face1, *interest5);
259 pit5->insertOrUpdateInRecord(face2, *interest5);
260 face3->m_sentInterests.clear();
261 forwarder.onOutgoingInterest(pit5, *face3);
262 BOOST_CHECK_EQUAL(face3->m_sentInterests.size(), 1);
263
264 // from local face and non-local face, to non-local face: OK
265 shared_ptr<Interest> interest6 = makeInterest("/localhop/6");
266 shared_ptr<pit::Entry> pit6 = pit.insert(*interest6).first;
267 pit6->insertOrUpdateInRecord(face1, *interest6);
268 pit6->insertOrUpdateInRecord(face2, *interest6);
269 face4->m_sentInterests.clear();
270 forwarder.onOutgoingInterest(pit6, *face4);
271 BOOST_CHECK_EQUAL(face4->m_sentInterests.size(), 1);
272}
273
Junxiao Shif3c07812014-03-11 21:48:49 -0700274BOOST_AUTO_TEST_CASE(StrategyDispatch)
275{
276 LimitedIo limitedIo;
277 Forwarder forwarder;
278 shared_ptr<Face> face1 = make_shared<DummyFace>();
279 shared_ptr<Face> face2 = make_shared<DummyFace>();
280 forwarder.addFace(face1);
281 forwarder.addFace(face2);
282
283 StrategyChoice& strategyChoice = forwarder.getStrategyChoice();
284 shared_ptr<DummyStrategy> strategyP = make_shared<DummyStrategy>(
285 boost::ref(forwarder), "ndn:/strategyP");
286 shared_ptr<DummyStrategy> strategyQ = make_shared<DummyStrategy>(
287 boost::ref(forwarder), "ndn:/strategyQ");
288 strategyChoice.install(strategyP);
289 strategyChoice.install(strategyQ);
290 strategyChoice.insert("ndn:/" , strategyP->getName());
291 strategyChoice.insert("ndn:/B", strategyQ->getName());
292
293 shared_ptr<Interest> interest1 = makeInterest("ndn:/A/1");
294 strategyP->m_afterReceiveInterest_count = 0;
295 strategyP->m_interestOutFace = face2;
296 forwarder.onInterest(*face1, *interest1);
297 BOOST_CHECK_EQUAL(strategyP->m_afterReceiveInterest_count, 1);
298
299 shared_ptr<Interest> interest2 = makeInterest("ndn:/B/2");
300 strategyQ->m_afterReceiveInterest_count = 0;
301 strategyQ->m_interestOutFace = face2;
302 forwarder.onInterest(*face1, *interest2);
303 BOOST_CHECK_EQUAL(strategyQ->m_afterReceiveInterest_count, 1);
304
305 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(5));
306
307 shared_ptr<Data> data1 = makeData("ndn:/A/1/a");
308 strategyP->m_beforeSatisfyPendingInterest_count = 0;
309 forwarder.onData(*face2, *data1);
310 BOOST_CHECK_EQUAL(strategyP->m_beforeSatisfyPendingInterest_count, 1);
311
312 shared_ptr<Data> data2 = makeData("ndn:/B/2/b");
313 strategyQ->m_beforeSatisfyPendingInterest_count = 0;
314 forwarder.onData(*face2, *data2);
315 BOOST_CHECK_EQUAL(strategyQ->m_beforeSatisfyPendingInterest_count, 1);
316
317 shared_ptr<Interest> interest3 = makeInterest("ndn:/A/3");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700318 interest3->setInterestLifetime(time::milliseconds(30));
Junxiao Shif3c07812014-03-11 21:48:49 -0700319 forwarder.onInterest(*face1, *interest3);
320 shared_ptr<Interest> interest4 = makeInterest("ndn:/B/4");
Alexander Afanasyeveb3197f2014-03-17 19:28:18 -0700321 interest4->setInterestLifetime(time::milliseconds(5000));
Junxiao Shif3c07812014-03-11 21:48:49 -0700322 forwarder.onInterest(*face1, *interest4);
323
324 strategyP->m_beforeExpirePendingInterest_count = 0;
325 strategyQ->m_beforeExpirePendingInterest_count = 0;
326 limitedIo.run(LimitedIo::UNLIMITED_OPS, time::milliseconds(100));
327 BOOST_CHECK_EQUAL(strategyP->m_beforeExpirePendingInterest_count, 1);
328 BOOST_CHECK_EQUAL(strategyQ->m_beforeExpirePendingInterest_count, 0);
329}
330
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700331BOOST_AUTO_TEST_SUITE_END()
332
Junxiao Shid9ee45c2014-02-27 15:38:11 -0700333} // namespace tests
Junxiao Shi8c8d2182014-01-30 22:33:00 -0700334} // namespace nfd