BOOST_FIXTURE_TEST_CASE(StatusDataset, DispatcherFixture) { static Block smallBlock("\x81\x01\0x01", 3); static Block largeBlock = [] () -> Block { EncodingBuffer encoder; for (size_t i = 0; i < 2500; ++i) { encoder.prependByte(1); } encoder.prependVarNumber(2500); encoder.prependVarNumber(129); return encoder.block(); }(); dispatcher.addStatusDataset("test/small", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext context) { context.append(smallBlock); context.append(smallBlock); context.append(smallBlock); context.end(); }); dispatcher.addStatusDataset("test/large", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext context) { context.append(largeBlock); context.append(largeBlock); context.append(largeBlock); context.end(); }); dispatcher.addStatusDataset("test/reject", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext context) { context.reject(); }); dispatcher.addTopPrefix("/root"); advanceClocks(time::milliseconds(1)); face->sentDatas.clear(); face->receive(*util::makeInterest("/root/test/small/%80%00")); // returns 403 face->receive(*util::makeInterest("/root/test/small/%80%00/invalid")); // returns 403 face->receive(*util::makeInterest("/root/test/small/%80%00/silent")); // silently ignored advanceClocks(time::milliseconds(1), 20); BOOST_CHECK_EQUAL(face->sentDatas.size(), 2); BOOST_CHECK(face->sentDatas[0].getContentType() == tlv::ContentType_Blob); BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[0].getContent().blockFromValue()).getCode(), 403); BOOST_CHECK(face->sentDatas[1].getContentType() == tlv::ContentType_Blob); BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[1].getContent().blockFromValue()).getCode(), 403); face->sentDatas.clear(); face->receive(*util::makeInterest("/root/test/small/valid")); advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(face->sentDatas.size(), 1); face->receive(*util::makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored face->receive(*util::makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(face->sentDatas.size(), 1); Block content = face->sentDatas[0].getContent(); BOOST_CHECK_NO_THROW(content.parse()); BOOST_CHECK_EQUAL(content.elements().size(), 3); BOOST_CHECK(content.elements()[0] == smallBlock); BOOST_CHECK(content.elements()[1] == smallBlock); BOOST_CHECK(content.elements()[2] == smallBlock); face->sentDatas.clear(); face->receive(*util::makeInterest("/root/test/large/valid")); advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(face->sentDatas.size(), 2); const auto& datas = face->sentDatas; content = [&datas] () -> Block { EncodingBuffer encoder; size_t valueLength = encoder.prependByteArray(datas[1].getContent().value(), datas[1].getContent().value_size()); valueLength += encoder.prependByteArray(datas[0].getContent().value(), datas[0].getContent().value_size()); encoder.prependVarNumber(valueLength); encoder.prependVarNumber(tlv::Content); return encoder.block(); }(); BOOST_CHECK_NO_THROW(content.parse()); BOOST_CHECK_EQUAL(content.elements().size(), 3); BOOST_CHECK(content.elements()[0] == largeBlock); BOOST_CHECK(content.elements()[1] == largeBlock); BOOST_CHECK(content.elements()[2] == largeBlock); face->sentDatas.clear(); face->receive(*util::makeInterest("/root/test/reject/%80%00/valid")); // returns nack advanceClocks(time::milliseconds(1)); BOOST_CHECK_EQUAL(face->sentDatas.size(), 1); BOOST_CHECK(face->sentDatas[0].getContentType() == tlv::ContentType_Nack); BOOST_CHECK_EQUAL(ControlResponse(face->sentDatas[0].getContent().blockFromValue()).getCode(), 400); }
BOOST_FIXTURE_TEST_CASE(StatusDataset, DispatcherFixture) { static Block smallBlock("\x81\x01\0x01", 3); static Block largeBlock = [] () -> Block { EncodingBuffer encoder; for (size_t i = 0; i < 2500; ++i) { encoder.prependByte(1); } encoder.prependVarNumber(2500); encoder.prependVarNumber(129); return encoder.block(); }(); dispatcher.addStatusDataset("test/small", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext& context) { context.append(smallBlock); context.append(smallBlock); context.append(smallBlock); context.end(); }); dispatcher.addStatusDataset("test/large", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext& context) { context.append(largeBlock); context.append(largeBlock); context.append(largeBlock); context.end(); }); dispatcher.addStatusDataset("test/reject", makeTestAuthorization(), [] (const Name& prefix, const Interest& interest, StatusDatasetContext& context) { context.reject(); }); dispatcher.addTopPrefix("/root"); advanceClocks(time::milliseconds(1)); face.sentData.clear(); face.receive(*util::makeInterest("/root/test/small/%80%00")); // returns 403 face.receive(*util::makeInterest("/root/test/small/%80%00/invalid")); // returns 403 face.receive(*util::makeInterest("/root/test/small/%80%00/silent")); // silently ignored advanceClocks(time::milliseconds(1), 20); BOOST_CHECK_EQUAL(face.sentData.size(), 2); BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Blob); BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 403); BOOST_CHECK(face.sentData[1].getContentType() == tlv::ContentType_Blob); BOOST_CHECK_EQUAL(ControlResponse(face.sentData[1].getContent().blockFromValue()).getCode(), 403); face.sentData.clear(); auto interestSmall = *util::makeInterest("/root/test/small/valid"); face.receive(interestSmall); advanceClocks(time::milliseconds(1), 10); // one data packet is generated and sent to both places BOOST_CHECK_EQUAL(face.sentData.size(), 1); BOOST_CHECK_EQUAL(storage.size(), 1); auto fetchedData = storage.find(interestSmall); BOOST_REQUIRE(fetchedData != nullptr); BOOST_CHECK(face.sentData[0].wireEncode() == fetchedData->wireEncode()); face.receive(*util::makeInterest(Name("/root/test/small/valid").appendVersion(10))); // should be ignored face.receive(*util::makeInterest(Name("/root/test/small/valid").appendSegment(20))); // should be ignored advanceClocks(time::milliseconds(1), 10); BOOST_CHECK_EQUAL(face.sentData.size(), 1); BOOST_CHECK_EQUAL(storage.size(), 1); Block content = face.sentData[0].getContent(); BOOST_CHECK_NO_THROW(content.parse()); BOOST_CHECK_EQUAL(content.elements().size(), 3); BOOST_CHECK(content.elements()[0] == smallBlock); BOOST_CHECK(content.elements()[1] == smallBlock); BOOST_CHECK(content.elements()[2] == smallBlock); storage.erase("/", true); // clear the storage face.sentData.clear(); face.receive(*util::makeInterest("/root/test/large/valid")); advanceClocks(time::milliseconds(1), 10); // two data packets are generated, the first one will be sent to both places // while the second one will only be inserted into the in-memory storage BOOST_CHECK_EQUAL(face.sentData.size(), 1); BOOST_CHECK_EQUAL(storage.size(), 2); // segment0 should be sent through the face const auto& component = face.sentData[0].getName().at(-1); BOOST_CHECK(component.isSegment()); BOOST_CHECK_EQUAL(component.toSegment(), 0); std::vector<Data> dataInStorage; std::copy(storage.begin(), storage.end(), std::back_inserter(dataInStorage)); // the Data sent through the face should be the same as the first Data in the storage BOOST_CHECK_EQUAL(face.sentData[0].getName(), dataInStorage[0].getName()); BOOST_CHECK(face.sentData[0].getContent() == dataInStorage[0].getContent()); content = [&dataInStorage] () -> Block { EncodingBuffer encoder; size_t valueLength = encoder.prependByteArray(dataInStorage[1].getContent().value(), dataInStorage[1].getContent().value_size()); valueLength += encoder.prependByteArray(dataInStorage[0].getContent().value(), dataInStorage[0].getContent().value_size()); encoder.prependVarNumber(valueLength); encoder.prependVarNumber(tlv::Content); return encoder.block(); }(); BOOST_CHECK_NO_THROW(content.parse()); BOOST_CHECK_EQUAL(content.elements().size(), 3); BOOST_CHECK(content.elements()[0] == largeBlock); BOOST_CHECK(content.elements()[1] == largeBlock); BOOST_CHECK(content.elements()[2] == largeBlock); storage.erase("/", true);// clear the storage face.sentData.clear(); face.receive(*util::makeInterest("/root/test/reject/%80%00/valid")); // returns nack advanceClocks(time::milliseconds(1)); BOOST_CHECK_EQUAL(face.sentData.size(), 1); BOOST_CHECK(face.sentData[0].getContentType() == tlv::ContentType_Nack); BOOST_CHECK_EQUAL(ControlResponse(face.sentData[0].getContent().blockFromValue()).getCode(), 400); BOOST_CHECK_EQUAL(storage.size(), 0); // the nack packet will not be inserted into the in-memory storage }