fw: pass parameters to Strategy subclass constructors

refs #3868

Change-Id: I1a09e7353c047d548065c4ed669d1f7993676428
diff --git a/tests/daemon/table/strategy-choice.t.cpp b/tests/daemon/table/strategy-choice.t.cpp
index 91634e9..a9042a9 100644
--- a/tests/daemon/table/strategy-choice.t.cpp
+++ b/tests/daemon/table/strategy-choice.t.cpp
@@ -32,94 +32,132 @@
 namespace nfd {
 namespace tests {
 
+class StrategyChoiceFixture : public BaseFixture
+{
+protected:
+  StrategyChoiceFixture()
+    : sc(forwarder.getStrategyChoice())
+  {
+  }
+
+  Name
+  insertAndGet(const Name& prefix, const Name& strategyName)
+  {
+    BOOST_REQUIRE(sc.insert(prefix, strategyName));
+    bool isFound;
+    Name foundName;
+    std::tie(isFound, foundName) = sc.get(prefix);
+    BOOST_REQUIRE(isFound);
+    return foundName;
+  }
+
+protected:
+  Forwarder forwarder;
+  StrategyChoice& sc;
+};
+
 BOOST_AUTO_TEST_SUITE(Table)
-BOOST_FIXTURE_TEST_SUITE(TestStrategyChoice, BaseFixture)
+BOOST_FIXTURE_TEST_SUITE(TestStrategyChoice, StrategyChoiceFixture)
 
 using fw::Strategy;
 
+BOOST_AUTO_TEST_CASE(Parameters)
+{
+  const Name strategyName("/strategy-choice-test-parameters/%FD%01");
+  DummyStrategy::registerAs(strategyName);
+
+  // no parameters
+  BOOST_CHECK_EQUAL(this->insertAndGet("/A", strategyName), strategyName);
+
+  // one parameter
+  Name oneParamName = Name(strategyName).append("param");
+  BOOST_CHECK_EQUAL(this->insertAndGet("/B", oneParamName), oneParamName);
+
+  // two parameters
+  Name twoParamName = Name(strategyName).append("x").append("y");
+  BOOST_CHECK_EQUAL(this->insertAndGet("/C", twoParamName), twoParamName);
+
+  // parameter without version is disallowed
+  Name oneParamUnversioned = strategyName.getPrefix(-1).append("param");
+  BOOST_CHECK_EQUAL(sc.insert("/D", oneParamUnversioned), false);
+}
+
 BOOST_AUTO_TEST_CASE(Get)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   install<DummyStrategy>(forwarder, nameP);
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
-
-  BOOST_CHECK(table.insert("ndn:/", nameP));
+  BOOST_CHECK(sc.insert("ndn:/", nameP));
   // { '/'=>P }
 
-  auto getRoot = table.get("ndn:/");
+  auto getRoot = sc.get("ndn:/");
   BOOST_CHECK_EQUAL(getRoot.first, true);
   BOOST_CHECK_EQUAL(getRoot.second, nameP);
 
-  auto getA = table.get("ndn:/A");
+  auto getA = sc.get("ndn:/A");
   BOOST_CHECK_EQUAL(getA.first, false);
 }
 
 BOOST_AUTO_TEST_CASE(FindEffectiveStrategy)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   Name nameZ("ndn:/strategy/Z");
   install<DummyStrategy>(forwarder, nameP);
   install<DummyStrategy>(forwarder, nameQ);
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
-
-  BOOST_CHECK(table.insert("ndn:/", nameP));
+  BOOST_CHECK(sc.insert("ndn:/", nameP));
   // { '/'=>P }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
 
-  BOOST_CHECK(table.insert("ndn:/A/B", nameP));
+  BOOST_CHECK(sc.insert("ndn:/A/B", nameP));
   // { '/'=>P, '/A/B'=>P }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
   // same instance
-  BOOST_CHECK_EQUAL(&table.findEffectiveStrategy("ndn:/"),
-                    &table.findEffectiveStrategy("ndn:/A/B"));
+  BOOST_CHECK_EQUAL(&sc.findEffectiveStrategy("ndn:/"),
+                    &sc.findEffectiveStrategy("ndn:/A/B"));
 
-  table.erase("ndn:/A"); // no effect
+  sc.erase("ndn:/A"); // no effect
   // { '/'=>P, '/A/B'=>P }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
 
-  BOOST_CHECK(table.insert("ndn:/A", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/A", nameQ));
   // { '/'=>P, '/A/B'=>P, '/A'=>Q }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
 
-  table.erase("ndn:/A/B");
+  sc.erase("ndn:/A/B");
   // { '/'=>P, '/A'=>Q }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameQ);
 
-  BOOST_CHECK(!table.insert("ndn:/", nameZ)); // non existent strategy
+  BOOST_CHECK(!sc.insert("ndn:/", nameZ)); // non existent strategy
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(table.insert("ndn:/A", nameP));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/A", nameP));
   // { '/'=>Q, '/A'=>P }
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/")   .getName(), nameQ);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/D")  .getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/")   .getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A")  .getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/A/B").getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/D")  .getName(), nameQ);
 }
 
 BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithPitEntry)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   install<DummyStrategy>(forwarder, nameP);
@@ -128,10 +166,8 @@
   shared_ptr<Data> dataABC = makeData("/A/B/C");
   Name fullName = dataABC->getFullName();
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
-
-  BOOST_CHECK(table.insert("/A", nameP));
-  BOOST_CHECK(table.insert(fullName, nameQ));
+  BOOST_CHECK(sc.insert("/A", nameP));
+  BOOST_CHECK(sc.insert(fullName, nameQ));
 
   Pit& pit = forwarder.getPit();
   shared_ptr<Interest> interestAB = makeInterest("/A/B");
@@ -139,29 +175,26 @@
   shared_ptr<Interest> interestFull = makeInterest(fullName);
   shared_ptr<pit::Entry> pitFull = pit.insert(*interestFull).first;
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitAB).getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(*pitFull).getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy(*pitAB).getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy(*pitFull).getName(), nameQ);
 }
 
 BOOST_AUTO_TEST_CASE(FindEffectiveStrategyWithMeasurementsEntry)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   install<DummyStrategy>(forwarder, nameP);
   install<DummyStrategy>(forwarder, nameQ);
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
-
-  BOOST_CHECK(table.insert("/A", nameP));
-  BOOST_CHECK(table.insert("/A/B/C", nameQ));
+  BOOST_CHECK(sc.insert("/A", nameP));
+  BOOST_CHECK(sc.insert("/A/B/C", nameQ));
 
   Measurements& measurements = forwarder.getMeasurements();
   measurements::Entry& mAB = measurements.get("/A/B");
   measurements::Entry& mABCD = measurements.get("/A/B/C/D");
 
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(mAB).getName(), nameP);
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy(mABCD).getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy(mAB).getName(), nameP);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy(mABCD).getName(), nameQ);
 }
 
 //XXX BOOST_CONCEPT_ASSERT((ForwardIterator<std::vector<int>::iterator>))
@@ -170,24 +203,21 @@
 
 BOOST_AUTO_TEST_CASE(Enumerate)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   install<DummyStrategy>(forwarder, nameP);
   install<DummyStrategy>(forwarder, nameQ);
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
+  sc.insert("ndn:/",      nameP);
+  sc.insert("ndn:/A/B",   nameQ);
+  sc.insert("ndn:/A/B/C", nameP);
+  sc.insert("ndn:/D",     nameP);
+  sc.insert("ndn:/E",     nameQ);
 
-  table.insert("ndn:/",      nameP);
-  table.insert("ndn:/A/B",   nameQ);
-  table.insert("ndn:/A/B/C", nameP);
-  table.insert("ndn:/D",     nameP);
-  table.insert("ndn:/E",     nameQ);
-
-  BOOST_CHECK_EQUAL(table.size(), 5);
+  BOOST_CHECK_EQUAL(sc.size(), 5);
 
   std::map<Name, Name> map; // namespace=>strategyName
-  for (StrategyChoice::const_iterator it = table.begin(); it != table.end(); ++it) {
+  for (StrategyChoice::const_iterator it = sc.begin(); it != sc.end(); ++it) {
     map[it->getPrefix()] = it->getStrategyName();
   }
   BOOST_CHECK_EQUAL(map.size(), 5);
@@ -211,37 +241,35 @@
 
 BOOST_AUTO_TEST_CASE(ClearStrategyInfo)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   install<DummyStrategy>(forwarder, nameP);
   install<DummyStrategy>(forwarder, nameQ);
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
   Measurements& measurements = forwarder.getMeasurements();
 
-  BOOST_CHECK(table.insert("ndn:/", nameP));
+  BOOST_CHECK(sc.insert("ndn:/", nameP));
   // { '/'=>P }
   measurements.get("ndn:/").insertStrategyInfo<PStrategyInfo>();
   measurements.get("ndn:/A").insertStrategyInfo<PStrategyInfo>();
   measurements.get("ndn:/A/B").insertStrategyInfo<PStrategyInfo>();
   measurements.get("ndn:/A/C").insertStrategyInfo<PStrategyInfo>();
 
-  BOOST_CHECK(table.insert("ndn:/A/B", nameP));
+  BOOST_CHECK(sc.insert("ndn:/A/B", nameP));
   // { '/'=>P, '/A/B'=>P }
   BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A/C").getStrategyInfo<PStrategyInfo>() != nullptr);
 
-  BOOST_CHECK(table.insert("ndn:/A", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/A", nameQ));
   // { '/'=>P, '/A/B'=>P, '/A'=>Q }
   BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() == nullptr);
   BOOST_CHECK(measurements.get("ndn:/A/B").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A/C").getStrategyInfo<PStrategyInfo>() == nullptr);
 
-  table.erase("ndn:/A/B");
+  sc.erase("ndn:/A/B");
   // { '/'=>P, '/A'=>Q }
   BOOST_CHECK(measurements.get("ndn:/").getStrategyInfo<PStrategyInfo>() != nullptr);
   BOOST_CHECK(measurements.get("ndn:/A").getStrategyInfo<PStrategyInfo>() == nullptr);
@@ -251,21 +279,19 @@
 
 BOOST_AUTO_TEST_CASE(EraseNameTreeEntry)
 {
-  Forwarder forwarder;
   Name nameP("ndn:/strategy/P");
   Name nameQ("ndn:/strategy/Q");
   install<DummyStrategy>(forwarder, nameP);
   install<DummyStrategy>(forwarder, nameQ);
 
   NameTree& nameTree = forwarder.getNameTree();
-  StrategyChoice& table = forwarder.getStrategyChoice();
 
-  table.insert("ndn:/", nameP);
+  sc.insert("ndn:/", nameP);
 
   size_t nNameTreeEntriesBefore = nameTree.size();
 
-  table.insert("ndn:/A/B", nameQ);
-  table.erase("ndn:/A/B");
+  sc.insert("ndn:/A/B", nameQ);
+  sc.erase("ndn:/A/B");
   BOOST_CHECK_EQUAL(nameTree.size(), nNameTreeEntriesBefore);
 }
 
@@ -280,8 +306,6 @@
   Name nameQ("ndn:/strategy/Q");
   Name nameQ5("ndn:/strategy/Q/%FD%05");
 
-  StrategyChoice& table = forwarder.getStrategyChoice();
-
   // install
   auto strategyP1 = make_unique<DummyStrategy>(ref(forwarder), nameP1);
   Strategy* instanceP1 = strategyP1.get();
@@ -295,56 +319,56 @@
   bool isInstalled = false;
   Strategy* installed = nullptr;
 
-  std::tie(isInstalled, installed) = table.install(std::move(strategyP1));
+  std::tie(isInstalled, installed) = sc.install(std::move(strategyP1));
   BOOST_CHECK_EQUAL(isInstalled, true);
   BOOST_CHECK_EQUAL(installed, instanceP1);
-  std::tie(isInstalled, installed) = table.install(std::move(strategyP1b));
+  std::tie(isInstalled, installed) = sc.install(std::move(strategyP1b));
   BOOST_CHECK_EQUAL(isInstalled, false);
   BOOST_CHECK_EQUAL(installed, instanceP1);
 
-  BOOST_CHECK_EQUAL(table.hasStrategy(nameP,  false), true);
-  BOOST_CHECK_EQUAL(table.hasStrategy(nameP,  true),  false);
-  BOOST_CHECK_EQUAL(table.hasStrategy(nameP1, true),  true);
+  BOOST_CHECK_EQUAL(sc.hasStrategy(nameP,  false), true);
+  BOOST_CHECK_EQUAL(sc.hasStrategy(nameP,  true),  false);
+  BOOST_CHECK_EQUAL(sc.hasStrategy(nameP1, true),  true);
 
-  BOOST_CHECK_EQUAL(table.install(std::move(strategyP2)).first, true);
-  BOOST_CHECK_EQUAL(table.install(std::move(strategy3)).first, true);
-  BOOST_CHECK_EQUAL(table.install(std::move(strategy4)).first, true);
-  BOOST_CHECK_EQUAL(table.install(std::move(strategyQ)).first, true);
-  BOOST_CHECK_EQUAL(table.install(std::move(strategyQ5)).first, true);
+  BOOST_CHECK_EQUAL(sc.install(std::move(strategyP2)).first, true);
+  BOOST_CHECK_EQUAL(sc.install(std::move(strategy3)).first, true);
+  BOOST_CHECK_EQUAL(sc.install(std::move(strategy4)).first, true);
+  BOOST_CHECK_EQUAL(sc.install(std::move(strategyQ)).first, true);
+  BOOST_CHECK_EQUAL(sc.install(std::move(strategyQ5)).first, true);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
   // exact match, { '/'=>Q }
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameQ);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(table.insert("ndn:/", nameP));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/", nameP));
   // { '/'=>P2 }
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameP2);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameP2);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(table.insert("ndn:/", nameP1));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/", nameP1));
   // { '/'=>P1 }
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameP1);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameP1);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(table.insert("ndn:/", nameP2));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(sc.insert("ndn:/", nameP2));
   // { '/'=>P2 }
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameP2);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameP2);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(! table.insert("ndn:/", "ndn:/strategy/A"));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(! sc.insert("ndn:/", "ndn:/strategy/A"));
   // not installed
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameQ);
 
-  BOOST_CHECK(table.insert("ndn:/", nameQ));
-  BOOST_CHECK(! table.insert("ndn:/", "ndn:/strategy/Z"));
+  BOOST_CHECK(sc.insert("ndn:/", nameQ));
+  BOOST_CHECK(! sc.insert("ndn:/", "ndn:/strategy/Z"));
   // not installed
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), nameQ);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), nameQ);
 
-  BOOST_CHECK(table.insert("ndn:/", nameP1));
-  BOOST_CHECK(table.insert("ndn:/", "ndn:/"));
+  BOOST_CHECK(sc.insert("ndn:/", nameP1));
+  BOOST_CHECK(sc.insert("ndn:/", "ndn:/"));
   // match one component longer only, { '/'=>4 }
-  BOOST_CHECK_EQUAL(table.findEffectiveStrategy("ndn:/").getName(), name4);
+  BOOST_CHECK_EQUAL(sc.findEffectiveStrategy("ndn:/").getName(), name4);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestStrategyChoice