table: eliminate Selectors from CS tests

refs #4805

Change-Id: I6ae48fc40e62aeeb41cde7530d6bfa6b6d5ef000
diff --git a/tests/daemon/table/cs-fixture.hpp b/tests/daemon/table/cs-fixture.hpp
new file mode 100644
index 0000000..15bf89e
--- /dev/null
+++ b/tests/daemon/table/cs-fixture.hpp
@@ -0,0 +1,113 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2014-2019,  Regents of the University of California,
+ *                           Arizona Board of Regents,
+ *                           Colorado State University,
+ *                           University Pierre & Marie Curie, Sorbonne University,
+ *                           Washington University in St. Louis,
+ *                           Beijing Institute of Technology,
+ *                           The University of Memphis.
+ *
+ * This file is part of NFD (Named Data Networking Forwarding Daemon).
+ * See AUTHORS.md for complete list of NFD authors and contributors.
+ *
+ * NFD is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Foundation,
+ * either version 3 of the License, or (at your option) any later version.
+ *
+ * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NFD_TESTS_DAEMON_TABLE_CS_FIXTURE_HPP
+#define NFD_TESTS_DAEMON_TABLE_CS_FIXTURE_HPP
+
+#include "table/cs.hpp"
+
+#include "tests/test-common.hpp"
+#include "tests/daemon/global-io-fixture.hpp"
+
+#include <cstring>
+
+namespace nfd {
+namespace cs {
+namespace tests {
+
+using namespace nfd::tests;
+
+#define CHECK_CS_FIND(expected) find([&] (uint32_t found) { BOOST_CHECK_EQUAL(expected, found); });
+
+class CsFixture : public GlobalIoTimeFixture
+{
+protected:
+  Name
+  insert(uint32_t id, const Name& name, const std::function<void(Data&)>& modifyData = nullptr,
+         bool isUnsolicited = false)
+  {
+    auto data = makeData(name);
+    data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
+
+    if (modifyData != nullptr) {
+      modifyData(*data);
+    }
+
+    data->wireEncode();
+    cs.insert(*data, isUnsolicited);
+
+    return data->getFullName();
+  }
+
+  Interest&
+  startInterest(const Name& name)
+  {
+    interest = make_shared<Interest>(name);
+    interest->setCanBePrefix(false);
+    return *interest;
+  }
+
+  void
+  find(const std::function<void(uint32_t)>& check)
+  {
+    bool hasResult = false;
+    cs.find(*interest,
+            [&] (const Interest& interest, const Data& data) {
+              hasResult = true;
+              const Block& content = data.getContent();
+              uint32_t found = 0;
+              std::memcpy(&found, content.value(), sizeof(found));
+              check(found);
+            },
+            bind([&] {
+              hasResult = true;
+              check(0);
+            }));
+
+    // current Cs::find implementation is synchronous
+    BOOST_CHECK(hasResult);
+  }
+
+  size_t
+  erase(const Name& prefix, size_t limit)
+  {
+    optional<size_t> nErased;
+    cs.erase(prefix, limit, [&] (size_t nErased1) { nErased = nErased1; });
+
+    // current Cs::erase implementation is synchronous
+    // if callback was not invoked, bad_optional_access would occur
+    return *nErased;
+  }
+
+protected:
+  Cs cs;
+  shared_ptr<Interest> interest;
+};
+
+} // namespace tests
+} // namespace cs
+} // namespace nfd
+
+#endif // NFD_TESTS_DAEMON_TABLE_CS_FIXTURE_HPP
diff --git a/tests/daemon/table/cs-policy-lru.t.cpp b/tests/daemon/table/cs-policy-lru.t.cpp
index bc28639..ed4fa7c 100644
--- a/tests/daemon/table/cs-policy-lru.t.cpp
+++ b/tests/daemon/table/cs-policy-lru.t.cpp
@@ -24,17 +24,13 @@
  */
 
 #include "table/cs-policy-lru.hpp"
-#include "table/cs.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/daemon/global-io-fixture.hpp"
+#include "tests/daemon/table/cs-fixture.hpp"
 
 namespace nfd {
 namespace cs {
 namespace tests {
 
-using namespace nfd::tests;
-
 BOOST_AUTO_TEST_SUITE(Table)
 BOOST_AUTO_TEST_SUITE(TestCsLru)
 
@@ -44,51 +40,45 @@
   BOOST_CHECK_EQUAL(policyNames.count("lru"), 1);
 }
 
-BOOST_FIXTURE_TEST_CASE(EvictOne, GlobalIoTimeFixture)
+BOOST_FIXTURE_TEST_CASE(EvictOne, CsFixture)
 {
-  Cs cs(3);
   cs.setPolicy(make_unique<LruPolicy>());
+  cs.setLimit(3);
 
-  cs.insert(*makeData("ndn:/A"));
-  cs.insert(*makeData("ndn:/B"));
-  cs.insert(*makeData("ndn:/C"));
+  insert(1, "/A");
+  insert(2, "/B");
+  insert(3, "/C");
   BOOST_CHECK_EQUAL(cs.size(), 3);
 
   // evict A
-  cs.insert(*makeData("ndn:/D"));
+  insert(4, "/D");
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/A"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/A");
+  CHECK_CS_FIND(0);
 
   // use C then B
-  cs.find(Interest("ndn:/C"),
-          bind([] { BOOST_CHECK(true); }),
-          bind([] { BOOST_CHECK(false); }));
-  cs.find(Interest("ndn:/B"),
-          bind([] { BOOST_CHECK(true); }),
-          bind([] { BOOST_CHECK(false); }));
+  startInterest("/C");
+  CHECK_CS_FIND(3);
+  startInterest("/B");
+  CHECK_CS_FIND(2);
 
   // evict D then C
-  cs.insert(*makeData("ndn:/E"));
+  insert(5, "/E");
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/D"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
-  cs.insert(*makeData("ndn:/F"));
+  startInterest("/D");
+  CHECK_CS_FIND(0);
+  insert(6, "/F");
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/C"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/C");
+  CHECK_CS_FIND(0);
 
   // refresh B
-  cs.insert(*makeData("ndn:/B"));
+  insert(12, "/B");
   // evict E
-  cs.insert(*makeData("ndn:/G"));
+  insert(7, "/G");
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/E"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/E");
+  CHECK_CS_FIND(0);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestCsLru
diff --git a/tests/daemon/table/cs-policy-priority-fifo.t.cpp b/tests/daemon/table/cs-policy-priority-fifo.t.cpp
index 37fcbc7..c059756 100644
--- a/tests/daemon/table/cs-policy-priority-fifo.t.cpp
+++ b/tests/daemon/table/cs-policy-priority-fifo.t.cpp
@@ -24,17 +24,13 @@
  */
 
 #include "table/cs-policy-priority-fifo.hpp"
-#include "table/cs.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/daemon/global-io-fixture.hpp"
+#include "tests/daemon/table/cs-fixture.hpp"
 
 namespace nfd {
 namespace cs {
 namespace tests {
 
-using namespace nfd::tests;
-
 BOOST_AUTO_TEST_SUITE(Table)
 BOOST_AUTO_TEST_SUITE(TestCsPriorityFifo)
 
@@ -44,107 +40,60 @@
   BOOST_CHECK_EQUAL(policyNames.count("priority_fifo"), 1);
 }
 
-BOOST_FIXTURE_TEST_CASE(EvictOne, GlobalIoTimeFixture)
+BOOST_FIXTURE_TEST_CASE(EvictOne, CsFixture)
 {
-  Cs cs(3);
   cs.setPolicy(make_unique<PriorityFifoPolicy>());
+  cs.setLimit(3);
 
-  shared_ptr<Data> dataA = makeData("ndn:/A");
-  dataA->setFreshnessPeriod(99999_ms);
-  dataA->wireEncode();
-  cs.insert(*dataA);
+  insert(1, "/A", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
+  insert(2, "/B", [] (Data& data) { data.setFreshnessPeriod(10_ms); });
+  insert(3, "/C", [] (Data& data) { data.setFreshnessPeriod(99999_ms); }, true);
+  advanceClocks(11_ms);
 
-  shared_ptr<Data> dataB = makeData("ndn:/B");
-  dataB->setFreshnessPeriod(10_ms);
-  dataB->wireEncode();
-  cs.insert(*dataB);
-
-  shared_ptr<Data> dataC = makeData("ndn:/C");
-  dataC->setFreshnessPeriod(99999_ms);
-  dataC->wireEncode();
-  cs.insert(*dataC, true);
-
-  this->advanceClocks(11_ms);
-
-  // evict unsolicited
-  shared_ptr<Data> dataD = makeData("ndn:/D");
-  dataD->setFreshnessPeriod(99999_ms);
-  dataD->wireEncode();
-  cs.insert(*dataD);
+  // evict /C (unsolicited)
+  insert(4, "/D", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/C"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/C");
+  CHECK_CS_FIND(0);
 
-  // evict stale
-  shared_ptr<Data> dataE = makeData("ndn:/E");
-  dataE->setFreshnessPeriod(99999_ms);
-  dataE->wireEncode();
-  cs.insert(*dataE);
+  // evict /B (stale)
+  insert(5, "/E", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/B"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/B");
+  CHECK_CS_FIND(0);
 
-  // evict fifo
-  shared_ptr<Data> dataF = makeData("ndn:/F");
-  dataF->setFreshnessPeriod(99999_ms);
-  dataF->wireEncode();
-  cs.insert(*dataF);
+  // evict /F (fresh)
+  insert(6, "/F", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/A"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/A");
+  CHECK_CS_FIND(0);
 }
 
-BOOST_FIXTURE_TEST_CASE(Refresh, GlobalIoTimeFixture)
+BOOST_FIXTURE_TEST_CASE(Refresh, CsFixture)
 {
-  Cs cs(3);
   cs.setPolicy(make_unique<PriorityFifoPolicy>());
+  cs.setLimit(3);
 
-  shared_ptr<Data> dataA = makeData("ndn:/A");
-  dataA->setFreshnessPeriod(99999_ms);
-  dataA->wireEncode();
-  cs.insert(*dataA);
+  insert(1, "/A", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
+  insert(2, "/B", [] (Data& data) { data.setFreshnessPeriod(10_ms); });
+  insert(3, "/C", [] (Data& data) { data.setFreshnessPeriod(10_ms); });
+  advanceClocks(11_ms);
 
-  shared_ptr<Data> dataB = makeData("ndn:/B");
-  dataB->setFreshnessPeriod(10_ms);
-  dataB->wireEncode();
-  cs.insert(*dataB);
-
-  shared_ptr<Data> dataC = makeData("ndn:/C");
-  dataC->setFreshnessPeriod(10_ms);
-  dataC->wireEncode();
-  cs.insert(*dataC);
-
-  this->advanceClocks(11_ms);
-
-  // refresh dataB
-  shared_ptr<Data> dataB2 = make_shared<Data>(*dataB);
-  dataB2->wireEncode();
-  cs.insert(*dataB2);
+  // refresh /B
+  insert(12, "/B", [] (Data& data) { data.setFreshnessPeriod(0_ms); });
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/A"),
-          bind([] { BOOST_CHECK(true); }),
-          bind([] { BOOST_CHECK(false); }));
+  startInterest("/A");
+  CHECK_CS_FIND(1);
+  startInterest("/B");
+  CHECK_CS_FIND(12);
+  startInterest("/C");
+  CHECK_CS_FIND(3);
 
-  cs.find(Interest("ndn:/B"),
-          bind([] { BOOST_CHECK(true); }),
-          bind([] { BOOST_CHECK(false); }));
-
-  cs.find(Interest("ndn:/C"),
-          bind([] { BOOST_CHECK(true); }),
-          bind([] { BOOST_CHECK(false); }));
-
-  // evict dataC stale
-  shared_ptr<Data> dataD = makeData("ndn:/D");
-  dataD->setFreshnessPeriod(99999_ms);
-  dataD->wireEncode();
-  cs.insert(*dataD);
+  // evict /C from stale queue
+  insert(4, "/D", [] (Data& data) { data.setFreshnessPeriod(99999_ms); });
   BOOST_CHECK_EQUAL(cs.size(), 3);
-  cs.find(Interest("ndn:/C"),
-          bind([] { BOOST_CHECK(false); }),
-          bind([] { BOOST_CHECK(true); }));
+  startInterest("/C");
+  CHECK_CS_FIND(0);
 }
 
 BOOST_AUTO_TEST_SUITE_END() // TestCsPriorityFifo
diff --git a/tests/daemon/table/cs.t.cpp b/tests/daemon/table/cs.t.cpp
index db980d2..85886da 100644
--- a/tests/daemon/table/cs.t.cpp
+++ b/tests/daemon/table/cs.t.cpp
@@ -25,106 +25,18 @@
 
 #include "table/cs.hpp"
 
-#include "tests/test-common.hpp"
-#include "tests/daemon/global-io-fixture.hpp"
+#include "tests/daemon/table/cs-fixture.hpp"
 
-#include <cstring>
-
-#include <ndn-cxx/exclude.hpp>
 #include <ndn-cxx/lp/tags.hpp>
-#include <ndn-cxx/util/sha256.hpp>
 
 namespace nfd {
 namespace cs {
 namespace tests {
 
-using namespace nfd::tests;
-
-#define CHECK_CS_FIND(expected) find([&] (uint32_t found) { BOOST_CHECK_EQUAL(expected, found); });
-
 BOOST_AUTO_TEST_SUITE(Table)
-BOOST_FIXTURE_TEST_SUITE(TestCs, GlobalIoFixture)
+BOOST_FIXTURE_TEST_SUITE(TestCs, CsFixture)
 
-class FindFixture : public GlobalIoTimeFixture
-{
-protected:
-  Name
-  insert(uint32_t id, const Name& name, const std::function<void(Data&)>& modifyData = nullptr)
-  {
-    shared_ptr<Data> data = makeData(name);
-    data->setContent(reinterpret_cast<const uint8_t*>(&id), sizeof(id));
-
-    if (modifyData != nullptr) {
-      modifyData(*data);
-    }
-
-    data->wireEncode();
-    m_cs.insert(*data);
-
-    return data->getFullName();
-  }
-
-  Interest&
-  startInterest(const Name& name)
-  {
-    m_interest = make_shared<Interest>(name);
-    return *m_interest;
-  }
-
-  void
-  find(const std::function<void(uint32_t)>& check)
-  {
-    bool hasResult = false;
-    m_cs.find(*m_interest,
-              [&] (const Interest& interest, const Data& data) {
-                hasResult = true;
-                const Block& content = data.getContent();
-                uint32_t found = 0;
-                std::memcpy(&found, content.value(), sizeof(found));
-                check(found);
-              },
-              bind([&] {
-                hasResult = true;
-                check(0);
-              }));
-
-    // current Cs::find implementation is synchronous
-    BOOST_CHECK(hasResult);
-  }
-
-  size_t
-  erase(const Name& prefix, size_t limit)
-  {
-    optional<size_t> nErased;
-    m_cs.erase(prefix, limit, [&] (size_t nErased1) { nErased = nErased1; });
-
-    // current Cs::erase implementation is synchronous
-    // if callback was not invoked, bad_optional_access would occur
-    return *nErased;
-  }
-
-protected:
-  Cs m_cs;
-  shared_ptr<Interest> m_interest;
-};
-
-BOOST_FIXTURE_TEST_SUITE(Find, FindFixture)
-
-BOOST_AUTO_TEST_CASE(EmptyDataName)
-{
-  insert(1, "/");
-
-  startInterest("/");
-  CHECK_CS_FIND(1);
-}
-
-BOOST_AUTO_TEST_CASE(EmptyInterestName)
-{
-  insert(1, "/A");
-
-  startInterest("/");
-  CHECK_CS_FIND(1);
-}
+BOOST_AUTO_TEST_SUITE(Find)
 
 BOOST_AUTO_TEST_CASE(ExactName)
 {
@@ -138,6 +50,19 @@
   CHECK_CS_FIND(2);
 }
 
+BOOST_AUTO_TEST_CASE(ExactName_CanBePrefix)
+{
+  insert(1, "/");
+  insert(2, "/A");
+  insert(3, "/A/B");
+  insert(4, "/A/C");
+  insert(5, "/D");
+
+  startInterest("/A")
+    .setCanBePrefix(true);
+  CHECK_CS_FIND(2);
+}
+
 BOOST_AUTO_TEST_CASE(FullName)
 {
   Name n1 = insert(1, "/A");
@@ -150,20 +75,19 @@
   CHECK_CS_FIND(2);
 }
 
-BOOST_AUTO_TEST_CASE(Leftmost)
+BOOST_AUTO_TEST_CASE(FullName_EmptyDataName)
 {
-  insert(1, "/A");
-  insert(2, "/B/p/1");
-  insert(3, "/B/p/2");
-  insert(4, "/B/q/1");
-  insert(5, "/B/q/2");
-  insert(6, "/C");
+  Name n1 = insert(1, "/");
+  Name n2 = insert(2, "/");
 
-  startInterest("/B");
+  startInterest(n1);
+  CHECK_CS_FIND(1);
+
+  startInterest(n2);
   CHECK_CS_FIND(2);
 }
 
-BOOST_AUTO_TEST_CASE(Rightmost)
+BOOST_AUTO_TEST_CASE(PrefixName)
 {
   insert(1, "/A");
   insert(2, "/B/p/1");
@@ -173,102 +97,18 @@
   insert(6, "/C");
 
   startInterest("/B")
-    .setChildSelector(1);
-  CHECK_CS_FIND(4);
+    .setCanBePrefix(true);
+  CHECK_CS_FIND(2);
 }
 
-BOOST_AUTO_TEST_CASE(MinSuffixComponents)
+BOOST_AUTO_TEST_CASE(PrefixName_NoCanBePrefix)
 {
-  insert(1, "/");
-  insert(2, "/A");
-  insert(3, "/B/1");
-  insert(4, "/C/1/2");
-  insert(5, "/D/1/2/3");
-  insert(6, "/E/1/2/3/4");
+  insert(1, "/B/p/1");
 
-  startInterest("/")
-    .setMinSuffixComponents(0);
-  CHECK_CS_FIND(1);
-
-  startInterest("/")
-    .setMinSuffixComponents(1);
-  CHECK_CS_FIND(1);
-
-  startInterest("/")
-    .setMinSuffixComponents(2);
-  CHECK_CS_FIND(2);
-
-  startInterest("/")
-    .setMinSuffixComponents(3);
-  CHECK_CS_FIND(3);
-
-  startInterest("/")
-    .setMinSuffixComponents(4);
-  CHECK_CS_FIND(4);
-
-  startInterest("/")
-    .setMinSuffixComponents(5);
-  CHECK_CS_FIND(5);
-
-  startInterest("/")
-    .setMinSuffixComponents(6);
-  CHECK_CS_FIND(6);
-
-  startInterest("/")
-    .setMinSuffixComponents(7);
+  startInterest("/B");
   CHECK_CS_FIND(0);
 }
 
-BOOST_AUTO_TEST_CASE(MaxSuffixComponents)
-{
-  insert(1, "/");
-  insert(2, "/A");
-  insert(3, "/B/2");
-  insert(4, "/C/2/3");
-  insert(5, "/D/2/3/4");
-  insert(6, "/E/2/3/4/5");
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(0);
-  CHECK_CS_FIND(0);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(1);
-  CHECK_CS_FIND(1);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(2);
-  CHECK_CS_FIND(2);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(3);
-  CHECK_CS_FIND(3);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(4);
-  CHECK_CS_FIND(4);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(5);
-  CHECK_CS_FIND(5);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(6);
-  CHECK_CS_FIND(6);
-
-  startInterest("/")
-    .setChildSelector(1)
-    .setMaxSuffixComponents(7);
-  CHECK_CS_FIND(6);
-}
-
 BOOST_AUTO_TEST_CASE(MustBeFresh)
 {
   insert(1, "/A/1"); // omitted FreshnessPeriod means FreshnessPeriod = 0 ms
@@ -278,107 +118,34 @@
 
   // lookup at exact same moment as insertion is not tested because this won't happen in reality
 
-  this->advanceClocks(500_ms); // @500ms
+  advanceClocks(500_ms); // @500ms
   startInterest("/A")
+    .setCanBePrefix(true)
     .setMustBeFresh(true);
   CHECK_CS_FIND(3);
 
-  this->advanceClocks(1500_ms); // @2s
+  advanceClocks(1500_ms); // @2s
   startInterest("/A")
+    .setCanBePrefix(true)
     .setMustBeFresh(true);
   CHECK_CS_FIND(4);
 
-  this->advanceClocks(3500_s); // @3502s
+  advanceClocks(3500_s); // @3502s
   startInterest("/A")
+    .setCanBePrefix(true)
     .setMustBeFresh(true);
   CHECK_CS_FIND(4);
 
-  this->advanceClocks(3500_s); // @7002s
+  advanceClocks(3500_s); // @7002s
   startInterest("/A")
+    .setCanBePrefix(true)
     .setMustBeFresh(true);
   CHECK_CS_FIND(0);
 }
 
-BOOST_AUTO_TEST_CASE(DigestOrder)
-{
-  Name n1 = insert(1, "/A");
-  Name n2 = insert(2, "/A");
-
-  uint32_t expectedLeftmost = 0, expectedRightmost = 0;
-  if (n1 < n2) {
-    expectedLeftmost = 1;
-    expectedRightmost = 2;
-  }
-  else {
-    BOOST_CHECK_MESSAGE(n1 != n2, "implicit digest collision detected");
-    expectedLeftmost = 2;
-    expectedRightmost = 1;
-  }
-
-  startInterest("/A")
-    .setChildSelector(0);
-  CHECK_CS_FIND(expectedLeftmost);
-  startInterest("/A")
-    .setChildSelector(1);
-  CHECK_CS_FIND(expectedRightmost);
-}
-
-BOOST_AUTO_TEST_CASE(DigestExclude)
-{
-  insert(1, "/A");
-  Name n2 = insert(2, "/A");
-  insert(3, "/A/B");
-
-  uint8_t digest00[ndn::util::Sha256::DIGEST_SIZE];
-  std::fill_n(digest00, sizeof(digest00), 0x00);
-  uint8_t digestFF[ndn::util::Sha256::DIGEST_SIZE];
-  std::fill_n(digestFF, sizeof(digestFF), 0xFF);
-
-  ndn::Exclude excludeDigest;
-  excludeDigest.excludeRange(
-    name::Component::fromImplicitSha256Digest(digest00, sizeof(digest00)),
-    name::Component::fromImplicitSha256Digest(digestFF, sizeof(digestFF)));
-
-  startInterest("/A")
-    .setChildSelector(0)
-    .setExclude(excludeDigest);
-  CHECK_CS_FIND(3);
-
-  startInterest("/A")
-    .setChildSelector(1)
-    .setExclude(excludeDigest);
-  CHECK_CS_FIND(3);
-
-  ndn::Exclude excludeGeneric;
-  excludeGeneric.excludeAfter(name::Component(static_cast<uint8_t*>(nullptr), 0));
-
-  startInterest("/A")
-    .setChildSelector(0)
-    .setExclude(excludeGeneric);
-  find([] (uint32_t found) { BOOST_CHECK(found == 1 || found == 2); });
-
-  startInterest("/A")
-    .setChildSelector(1)
-    .setExclude(excludeGeneric);
-  find([] (uint32_t found) { BOOST_CHECK(found == 1 || found == 2); });
-
-  ndn::Exclude exclude2 = excludeGeneric;
-  exclude2.excludeOne(n2.get(-1));
-
-  startInterest("/A")
-    .setChildSelector(0)
-    .setExclude(exclude2);
-  CHECK_CS_FIND(1);
-
-  startInterest("/A")
-    .setChildSelector(1)
-    .setExclude(exclude2);
-  CHECK_CS_FIND(1);
-}
-
 BOOST_AUTO_TEST_SUITE_END() // Find
 
-BOOST_FIXTURE_TEST_CASE(Erase, FindFixture)
+BOOST_AUTO_TEST_CASE(Erase)
 {
   insert(1, "/A/B/1");
   insert(2, "/A/B/2");
@@ -386,10 +153,10 @@
   insert(4, "/A/C/4");
   insert(5, "/D/5");
   insert(6, "/E/6");
-  BOOST_CHECK_EQUAL(m_cs.size(), 6);
+  BOOST_CHECK_EQUAL(cs.size(), 6);
 
   BOOST_CHECK_EQUAL(erase("/A", 3), 3);
-  BOOST_CHECK_EQUAL(m_cs.size(), 3);
+  BOOST_CHECK_EQUAL(cs.size(), 3);
   int nDataUnderA = 0;
   startInterest("/A/B/1");
   find([&] (uint32_t found) { nDataUnderA += static_cast<int>(found > 0); });
@@ -402,42 +169,42 @@
   BOOST_CHECK_EQUAL(nDataUnderA, 1);
 
   BOOST_CHECK_EQUAL(erase("/D", 2), 1);
-  BOOST_CHECK_EQUAL(m_cs.size(), 2);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
   startInterest("/D/5");
   CHECK_CS_FIND(0);
 
   BOOST_CHECK_EQUAL(erase("/F", 2), 0);
-  BOOST_CHECK_EQUAL(m_cs.size(), 2);
+  BOOST_CHECK_EQUAL(cs.size(), 2);
 }
 
 // When the capacity limit is set to zero, Data cannot be inserted;
 // this test case covers this situation.
 // The behavior of non-zero capacity limit depends on the eviction policy,
 // and is tested in policy test suites.
-BOOST_FIXTURE_TEST_CASE(ZeroCapacity, FindFixture)
+BOOST_AUTO_TEST_CASE(ZeroCapacity)
 {
-  m_cs.setLimit(0);
+  cs.setLimit(0);
 
-  BOOST_CHECK_EQUAL(m_cs.getLimit(), 0);
-  BOOST_CHECK_EQUAL(m_cs.size(), 0);
-  BOOST_CHECK(m_cs.begin() == m_cs.end());
+  BOOST_CHECK_EQUAL(cs.getLimit(), 0);
+  BOOST_CHECK_EQUAL(cs.size(), 0);
+  BOOST_CHECK(cs.begin() == cs.end());
 
   insert(1, "/A");
-  BOOST_CHECK_EQUAL(m_cs.size(), 0);
+  BOOST_CHECK_EQUAL(cs.size(), 0);
 
   startInterest("/A");
   CHECK_CS_FIND(0);
 }
 
-BOOST_FIXTURE_TEST_CASE(EnablementFlags, FindFixture)
+BOOST_AUTO_TEST_CASE(EnablementFlags)
 {
-  BOOST_CHECK_EQUAL(m_cs.shouldAdmit(), true);
-  BOOST_CHECK_EQUAL(m_cs.shouldServe(), true);
+  BOOST_CHECK_EQUAL(cs.shouldAdmit(), true);
+  BOOST_CHECK_EQUAL(cs.shouldServe(), true);
 
   insert(1, "/A");
-  m_cs.enableAdmit(false);
+  cs.enableAdmit(false);
   insert(2, "/B");
-  m_cs.enableAdmit(true);
+  cs.enableAdmit(true);
   insert(3, "/C");
 
   startInterest("/A");
@@ -447,20 +214,20 @@
   startInterest("/C");
   CHECK_CS_FIND(3);
 
-  m_cs.enableServe(false);
+  cs.enableServe(false);
   startInterest("/A");
   CHECK_CS_FIND(0);
   startInterest("/C");
   CHECK_CS_FIND(0);
 
-  m_cs.enableServe(true);
+  cs.enableServe(true);
   startInterest("/A");
   CHECK_CS_FIND(1);
   startInterest("/C");
   CHECK_CS_FIND(3);
 }
 
-BOOST_FIXTURE_TEST_CASE(CachePolicyNoCache, FindFixture)
+BOOST_AUTO_TEST_CASE(CachePolicyNoCache)
 {
   insert(1, "/A", [] (Data& data) {
     data.setTag(make_shared<lp::CachePolicyTag>(
@@ -473,8 +240,6 @@
 
 BOOST_AUTO_TEST_CASE(Enumeration)
 {
-  Cs cs;
-
   Name nameA("/A");
   Name nameAB("/A/B");
   Name nameABC("/A/B/C");
@@ -483,7 +248,7 @@
   BOOST_CHECK_EQUAL(cs.size(), 0);
   BOOST_CHECK(cs.begin() == cs.end());
 
-  cs.insert(*makeData(nameABC));
+  insert(123, nameABC);
   BOOST_CHECK_EQUAL(cs.size(), 1);
   BOOST_CHECK(cs.begin() != cs.end());
   BOOST_CHECK(cs.begin()->getName() == nameABC);
@@ -495,9 +260,9 @@
   BOOST_CHECK(j++ == cs.begin());
   BOOST_CHECK(j == cs.end());
 
-  cs.insert(*makeData(nameA));
-  cs.insert(*makeData(nameAB));
-  cs.insert(*makeData(nameD));
+  insert(1, nameA);
+  insert(12, nameAB);
+  insert(4, nameD);
 
   std::set<Name> expected = {nameA, nameAB, nameABC, nameD};
   std::set<Name> actual;
diff --git a/tests/other/cs-benchmark.cpp b/tests/other/cs-benchmark.cpp
index e9226ef..252e6fd 100644
--- a/tests/other/cs-benchmark.cpp
+++ b/tests/other/cs-benchmark.cpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /*
- * Copyright (c) 2014-2017,  Regents of the University of California,
+ * Copyright (c) 2014-2019,  Regents of the University of California,
  *                           Arizona Board of Regents,
  *                           Colorado State University,
  *                           University Pierre & Marie Curie, Sorbonne University,
@@ -115,7 +115,9 @@
     std::vector<shared_ptr<Interest>> workload(count);
     for (size_t i = 0; i < count; ++i) {
       Name name = genName(i);
-      workload[i] = make_shared<Interest>(name);
+      auto interest = make_shared<Interest>(name);
+      interest->setCanBePrefix(false);
+      workload[i] = interest;
     }
     return workload;
   }
@@ -142,7 +144,7 @@
   constexpr size_t N_WORKLOAD = CS_CAPACITY * 2;
   constexpr size_t REPEAT = 4;
 
-  std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_WORKLOAD);
+  auto interestWorkload = makeInterestWorkload(N_WORKLOAD);
   std::vector<shared_ptr<Data>> dataWorkload[REPEAT];
   for (size_t j = 0; j < REPEAT; ++j) {
     dataWorkload[j] = makeDataWorkload(N_WORKLOAD);
@@ -184,8 +186,8 @@
   std::cout << "insert-find(hit) " << (N_WORKLOAD * REPEAT) << ": " << d << std::endl;
 }
 
-// find(leftmost) hit
-BOOST_FIXTURE_TEST_CASE(Leftmost, CsBenchmarkFixture)
+// find(CanBePrefix) hit
+BOOST_FIXTURE_TEST_CASE(FindCanBePrefixHit, CsBenchmarkFixture)
 {
   constexpr size_t N_CHILDREN = 10;
   constexpr size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
@@ -193,12 +195,11 @@
 
   std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
   for (auto&& interest : interestWorkload) {
-    interest->setChildSelector(0);
+    interest->setCanBePrefix(true);
     for (size_t j = 0; j < N_CHILDREN; ++j) {
       Name name = interest->getName();
       name.appendNumber(j);
-      shared_ptr<Data> data = makeData(name);
-      cs.insert(*data, false);
+      cs.insert(*makeData(name), false);
     }
   }
   BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
@@ -211,37 +212,7 @@
     }
   });
 
-  std::cout << "find(leftmost) " << (N_INTERESTS * N_CHILDREN * REPEAT) << ": " << d << std::endl;
-}
-
-// find(rightmost) hit
-BOOST_FIXTURE_TEST_CASE(Rightmost, CsBenchmarkFixture)
-{
-  constexpr size_t N_CHILDREN = 10;
-  constexpr size_t N_INTERESTS = CS_CAPACITY / N_CHILDREN;
-  constexpr size_t REPEAT = 4;
-
-  std::vector<shared_ptr<Interest>> interestWorkload = makeInterestWorkload(N_INTERESTS);
-  for (auto&& interest : interestWorkload) {
-    interest->setChildSelector(1);
-    for (size_t j = 0; j < N_CHILDREN; ++j) {
-      Name name = interest->getName();
-      name.appendNumber(j);
-      shared_ptr<Data> data = makeData(name);
-      cs.insert(*data, false);
-    }
-  }
-  BOOST_REQUIRE(cs.size() == N_INTERESTS * N_CHILDREN);
-
-  time::microseconds d = timedRun([&] {
-    for (size_t j = 0; j < REPEAT; ++j) {
-      for (const auto& interest : interestWorkload) {
-        find(*interest);
-      }
-    }
-  });
-
-  std::cout << "find(rightmost) " << (N_INTERESTS * N_CHILDREN * REPEAT) << ": " << d << std::endl;
+  std::cout << "find(CanBePrefix-hit) " << (N_INTERESTS * N_CHILDREN * REPEAT) << ": " << d << std::endl;
 }
 
 } // namespace tests