// manually close a face BOOST_AUTO_TEST_CASE_TEMPLATE(ManualClose, A, EndToEndAddresses) { LimitedIo limitedIo; UdpFactory factory; shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1()); shared_ptr<Face> face1; unique_ptr<FaceHistory> history1; factory.createFace(A::getFaceUri2(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT, [&] (shared_ptr<Face> newFace) { face1 = newFace; history1.reset(new FaceHistory(*face1, limitedIo)); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::milliseconds(100)); BOOST_REQUIRE(face1 != nullptr); BOOST_CHECK_EQUAL(channel1->size(), 1); face1->close(); getGlobalIoService().poll(); BOOST_CHECK_EQUAL(history1->failures.size(), 1); BOOST_CHECK_EQUAL(channel1->size(), 0); }
BOOST_FIXTURE_TEST_CASE(CapacityUp, PeriodicalInsertionFixture) { LimitedIo limitedIo; ssize_t cap0 = dnl.m_capacity; const int RATE = DeadNonceList::INITIAL_CAPACITY * 3; this->setRate(RATE); limitedIo.defer(LIFETIME * 10); ssize_t cap1 = dnl.m_capacity; BOOST_CHECK_LT(std::abs(cap1 - RATE), std::abs(cap0 - RATE)); }
// automatically close an idle incoming face BOOST_AUTO_TEST_CASE_TEMPLATE(IdleClose, A, EndToEndAddresses) { LimitedIo limitedIo; UdpFactory factory; // channel1 is listening shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1(), time::seconds(2)); shared_ptr<Face> face1; unique_ptr<FaceHistory> history1; channel1->listen([&] (shared_ptr<Face> newFace) { BOOST_CHECK(face1 == nullptr); face1 = newFace; history1.reset(new FaceHistory(*face1, limitedIo)); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); // face2 (on channel2) connects to channel1 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2(), time::seconds(2)); shared_ptr<Face> face2; unique_ptr<FaceHistory> history2; boost::asio::ip::address ipAddress = boost::asio::ip::address::from_string(A::getLocalIp()); udp::Endpoint endpoint(ipAddress, boost::lexical_cast<uint16_t>(A::getPort1())); channel2->connect(endpoint, [&] (shared_ptr<Face> newFace) { face2 = newFace; history2.reset(new FaceHistory(*face2, limitedIo)); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::milliseconds(100)); // 1 create (on channel2) BOOST_REQUIRE(face2 != nullptr); BOOST_CHECK_EQUAL(face2->getPersistency(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT); BOOST_CHECK_EQUAL(face2->isMultiAccess(), false); // face2 sends to channel1, creates face1 shared_ptr<Interest> interest2 = makeInterest("/I2"); face2->sendInterest(*interest2); limitedIo.run(2, time::seconds(1)); // 1 accept (on channel1), 1 receive (on face1) BOOST_CHECK_EQUAL(channel1->size(), 1); BOOST_REQUIRE(face1 != nullptr); BOOST_CHECK_EQUAL(face1->getPersistency(), ndn::nfd::FACE_PERSISTENCY_ON_DEMAND); BOOST_CHECK_EQUAL(face1->isMultiAccess(), false); limitedIo.defer(time::seconds(1)); BOOST_CHECK_EQUAL(history1->failures.size(), 0); // face1 is not idle BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed limitedIo.defer(time::seconds(4)); BOOST_CHECK_EQUAL(history1->failures.size(), 1); // face1 is idle and automatically closed BOOST_CHECK_EQUAL(channel1->size(), 0); BOOST_CHECK_EQUAL(history2->failures.size(), 0); // face2 is outgoing face and never closed }
// channel accepting multiple incoming connections BOOST_AUTO_TEST_CASE_TEMPLATE(MultipleAccepts, A, EndToEndAddresses) { LimitedIo limitedIo; UdpFactory factory; // channel1 is listening shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1()); std::vector<shared_ptr<Face>> faces1; channel1->listen([&] (shared_ptr<Face> newFace) { faces1.push_back(newFace); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); // face2 (on channel2) connects to channel1 shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2()); BOOST_CHECK_NE(channel1, channel2); shared_ptr<Face> face2; boost::asio::ip::address ipAddress2 = boost::asio::ip::address::from_string(A::getLocalIp()); udp::Endpoint endpoint2(ipAddress2, boost::lexical_cast<uint16_t>(A::getPort1())); channel2->connect(endpoint2, [&] (shared_ptr<Face> newFace) { face2 = newFace; limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::seconds(1)); // 1 create (on channel2) BOOST_REQUIRE(face2 != nullptr); BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face2 sends something // face3 (on channel3) connects to channel1 shared_ptr<UdpChannel> channel3 = factory.createChannel(A::getLocalIp(), A::getPort3()); BOOST_CHECK_NE(channel1, channel3); shared_ptr<Face> face3; boost::asio::ip::address ipAddress3 = boost::asio::ip::address::from_string(A::getLocalIp()); udp::Endpoint endpoint3(ipAddress3, boost::lexical_cast<uint16_t>(A::getPort1())); channel3->connect(endpoint3, [&] (shared_ptr<Face> newFace) { face3 = newFace; limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::seconds(1)); // 1 create (on channel3) BOOST_REQUIRE(face3 != nullptr); BOOST_CHECK_EQUAL(faces1.size(), 0); // channel1 won't create face until face3 sends something // face2 sends to channel1 shared_ptr<Interest> interest2 = makeInterest("/I2"); face2->sendInterest(*interest2); limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1) BOOST_REQUIRE_EQUAL(faces1.size(), 1); BOOST_CHECK_EQUAL(channel1->size(), 1); BOOST_CHECK_EQUAL(faces1.at(0)->getRemoteUri(), A::getFaceUri2()); // face3 sends to channel1 shared_ptr<Data> data3 = makeData("/D3"); face3->sendData(*data3); limitedIo.run(1, time::milliseconds(100)); // 1 accept (on channel1) BOOST_REQUIRE_EQUAL(faces1.size(), 2); BOOST_CHECK_EQUAL(channel1->size(), 2); BOOST_CHECK_EQUAL(faces1.at(1)->getRemoteUri(), A::getFaceUri3()); }
// end to end communication BOOST_AUTO_TEST_CASE_TEMPLATE(EndToEnd, A, EndToEndAddresses) { LimitedIo limitedIo; UdpFactory factory; shared_ptr<UdpChannel> channel1 = factory.createChannel(A::getLocalIp(), A::getPort1()); // face1 (on channel1) connects to face2 (on channel2, to be created) shared_ptr<Face> face1; unique_ptr<FaceHistory> history1; factory.createFace(A::getFaceUri2(), ndn::nfd::FACE_PERSISTENCY_PERSISTENT, [&] (shared_ptr<Face> newFace) { face1 = newFace; history1.reset(new FaceHistory(*face1, limitedIo)); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::seconds(1)); BOOST_REQUIRE(face1 != nullptr); BOOST_CHECK_EQUAL(face1->getRemoteUri(), A::getFaceUri2()); BOOST_CHECK_EQUAL(face1->getLocalUri(), A::getFaceUri1()); BOOST_CHECK_EQUAL(face1->isLocal(), false); // UdpFace is never local BOOST_CHECK_EQUAL(face1->getCounters().getNInBytes(), 0); BOOST_CHECK_EQUAL(face1->getCounters().getNOutBytes(), 0); // channel2 creation must be after face1 creation, // otherwise channel2's endpoint would be prohibited shared_ptr<UdpChannel> channel2 = factory.createChannel(A::getLocalIp(), A::getPort2()); shared_ptr<Face> face2; unique_ptr<FaceHistory> history2; channel2->listen([&] (shared_ptr<Face> newFace) { BOOST_CHECK(face2 == nullptr); face2 = newFace; history2.reset(new FaceHistory(*face2, limitedIo)); limitedIo.afterOp(); }, [] (const std::string& reason) { BOOST_ERROR(reason); }); limitedIo.run(1, time::seconds(1)); BOOST_CHECK(face2 == nullptr); // face2 shouldn't be created until face1 sends something shared_ptr<Interest> interest1 = makeInterest("/I1"); shared_ptr<Interest> interest2 = makeInterest("/I2"); shared_ptr<Data> data1 = makeData("/D1"); shared_ptr<Data> data2 = makeData("/D2"); // face1 sends to channel2, creates face2 face1->sendInterest(*interest1); face1->sendData(*data1); face1->sendData(*data1); face1->sendData(*data1); size_t nBytesSent1 = interest1->wireEncode().size() + 3 * data1->wireEncode().size(); limitedIo.run(5, time::seconds(1)); // 1 accept, 4 receives BOOST_REQUIRE(face2 != nullptr); BOOST_CHECK_EQUAL(face2->getRemoteUri(), A::getFaceUri1()); BOOST_CHECK_EQUAL(face2->getLocalUri(), A::getFaceUri2()); BOOST_CHECK_EQUAL(face2->isLocal(), false); // UdpFace is never local BOOST_CHECK_EQUAL(face2->getCounters().getNInBytes(), nBytesSent1); BOOST_CHECK_EQUAL(face2->getCounters().getNOutBytes(), 0); BOOST_REQUIRE_EQUAL(history2->receivedInterests.size(), 1); BOOST_CHECK_EQUAL(history2->receivedInterests.front().getName(), interest1->getName()); BOOST_REQUIRE_EQUAL(history2->receivedData.size(), 3); BOOST_CHECK_EQUAL(history2->receivedData.front().getName(), data1->getName()); // face2 sends to face1 face2->sendInterest(*interest2); face2->sendInterest(*interest2); face2->sendInterest(*interest2); face2->sendData(*data2); size_t nBytesSent2 = 3 * interest2->wireEncode().size() + data2->wireEncode().size(); limitedIo.run(4, time::seconds(1)); // 4 receives BOOST_REQUIRE_EQUAL(history1->receivedInterests.size(), 3); BOOST_CHECK_EQUAL(history1->receivedInterests.front().getName(), interest2->getName()); BOOST_REQUIRE_EQUAL(history1->receivedData.size(), 1); BOOST_CHECK_EQUAL(history1->receivedData.front().getName(), data2->getName()); // counters const FaceCounters& counters1 = face1->getCounters(); BOOST_CHECK_EQUAL(counters1.getNInInterests(), 3); BOOST_CHECK_EQUAL(counters1.getNInDatas(), 1); BOOST_CHECK_EQUAL(counters1.getNOutInterests(), 1); BOOST_CHECK_EQUAL(counters1.getNOutDatas(), 3); BOOST_CHECK_EQUAL(counters1.getNInBytes(), nBytesSent2); BOOST_CHECK_EQUAL(counters1.getNOutBytes(), nBytesSent1); const FaceCounters& counters2 = face2->getCounters(); BOOST_CHECK_EQUAL(counters2.getNInInterests(), 1); BOOST_CHECK_EQUAL(counters2.getNInDatas(), 3); BOOST_CHECK_EQUAL(counters2.getNOutInterests(), 3); BOOST_CHECK_EQUAL(counters2.getNOutDatas(), 1); BOOST_CHECK_EQUAL(counters2.getNInBytes(), nBytesSent1); BOOST_CHECK_EQUAL(counters2.getNOutBytes(), nBytesSent2); }