ndn-handle: Implement TCP backdoor to inject data packets into repo

Change-Id: I74d0698f914a2e68d47ede427c7f36b3ba3b4f47
Refs: #1485
diff --git a/tests/dataset-fixtures.hpp b/tests/dataset-fixtures.hpp
new file mode 100644
index 0000000..8dfeb78
--- /dev/null
+++ b/tests/dataset-fixtures.hpp
@@ -0,0 +1,210 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef REPO_TESTS_DATASET_FIXTURES_HPP
+#define REPO_TESTS_DATASET_FIXTURES_HPP
+
+#include <ndn-cpp-dev/security/key-chain.hpp>
+
+namespace repo {
+namespace tests {
+
+static inline ndn::shared_ptr<ndn::Data>
+createData(const ndn::Name& name)
+{
+  static ndn::KeyChain keyChain;
+  static std::vector<uint8_t> content(1500, '-');
+
+  ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>();
+  data->setName(name);
+  data->setContent(&content[0], content.size());
+  keyChain.sign(*data);
+
+  return data;
+}
+
+
+class DatasetBase
+{
+public:
+  typedef std::list<ndn::shared_ptr<ndn::Data> > DataContainer;
+  DataContainer data;
+
+  typedef std::list<std::pair<ndn::Interest, ndn::shared_ptr<ndn::Data> > > InterestContainer;
+  InterestContainer interests;
+};
+
+
+template<size_t N>
+class BaseSmoketestFixture : public DatasetBase
+{
+public:
+  static const std::string&
+  getName()
+  {
+    static std::string name = "BaseSmoketest";
+    return name;
+  }
+
+  BaseSmoketestFixture()
+  {
+    ndn::Name baseName("/x/y/z/test/1");
+    for (size_t i = 0; i < N; i++) {
+      ndn::Name name(baseName);
+      name.appendSegment(i);
+      ndn::shared_ptr<Data> data = createData(name);
+      this->data.push_back(data);
+
+      this->interests.push_back(std::make_pair(Interest(name), data));
+    }
+  }
+};
+
+
+class BaseTestFixture : public DatasetBase
+{
+public:
+  static const std::string&
+  getName()
+  {
+    static std::string name = "BaseTest";
+    return name;
+  }
+
+  BaseTestFixture()
+  {
+    this->data.push_back(createData("/a"));
+    this->interests.push_back(std::make_pair(Interest("/a"), this->data.back()));
+
+    this->data.push_back(createData("/a/b"));
+    this->interests.push_back(std::make_pair(Interest("/a/b"), this->data.back()));
+
+    this->data.push_back(createData("/a/b/c"));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c"), this->data.back()));
+
+    this->data.push_back(createData("/a/b/c/d"));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d"), this->data.back()));
+  }
+};
+
+
+class FetchByPrefixTestFixture : public DatasetBase
+{
+public:
+  static const std::string&
+  getName()
+  {
+    static std::string name = "FetchByPrefix";
+    return name;
+  }
+
+  FetchByPrefixTestFixture()
+  {
+    this->data.push_back(createData("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z"));
+    this->interests.push_back(std::make_pair(Interest("/a"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t"),
+                                             this->data.back()));
+    this->interests.push_back(std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u"),
+                                             this->data.back()));
+    this->interests.push_back(
+       std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v"),
+                      this->data.back()));
+    this->interests.push_back(
+       std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w"),
+                      this->data.back()));
+    this->interests.push_back(
+      std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x"),
+                     this->data.back()));
+    this->interests.push_back(
+      std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y"),
+                     this->data.back()));
+    this->interests.push_back(
+      std::make_pair(Interest("/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/x/y/z"),
+                     this->data.back()));
+  }
+};
+
+
+class SelectorTestFixture : public DatasetBase
+{
+public:
+  static const std::string&
+  getName()
+  {
+    static std::string name = "SelectorTest";
+    return name;
+  }
+
+  SelectorTestFixture()
+  {
+    this->data.push_back(createData("/a/1"));
+    this->data.push_back(createData("/b/1"));
+    this->interests.push_back(std::make_pair(Interest()
+                                         .setName("/b")
+                                         .setSelectors(Selectors()
+                                                         .setChildSelector(0)),
+                                       this->data.back()));
+
+    this->data.push_back(createData("/c/1"));
+    this->data.push_back(createData("/b/99"));
+    this->interests.push_back(std::make_pair(Interest()
+                                         .setName("/b")
+                                         .setSelectors(Selectors()
+                                                         .setChildSelector(1)),
+                                       this->data.back()));
+    this->data.push_back(createData("/b/5"));
+    this->data.push_back(createData("/b/55"));
+  }
+};
+
+
+typedef boost::mpl::vector< BaseTestFixture,
+                            FetchByPrefixTestFixture,
+                            SelectorTestFixture,
+                            BaseSmoketestFixture<1>,
+                            BaseSmoketestFixture<100> > DatasetFixtures;
+
+} // namespace tests
+} // namespace repo
+
+#endif // REPO_TESTS_DATASET_FIXTURES_HPP
diff --git a/tests/test-repo-command-parameter.cpp b/tests/repo-command-parameter.cpp
similarity index 87%
rename from tests/test-repo-command-parameter.cpp
rename to tests/repo-command-parameter.cpp
index 76ca548..9b70636 100644
--- a/tests/test-repo-command-parameter.cpp
+++ b/tests/repo-command-parameter.cpp
@@ -10,12 +10,13 @@
 #include <boost/test/unit_test.hpp>
 
 namespace repo {
+namespace tests {
 
-BOOST_AUTO_TEST_SUITE(TestRepoCommandParameter)
+BOOST_AUTO_TEST_SUITE(RepoCommandParameter)
 
-BOOST_AUTO_TEST_CASE(TestRepoCommandParameter)
+BOOST_AUTO_TEST_CASE(EncodeDecode)
 {
-  RepoCommandParameter parameter;
+  repo::RepoCommandParameter parameter;
   parameter.setName("/a/b/c");
   parameter.setStartBlockId(1);
   parameter.setEndBlockId(100);
@@ -40,9 +41,9 @@
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
 
-  BOOST_REQUIRE_NO_THROW(RepoCommandParameter(wire));
+  BOOST_REQUIRE_NO_THROW(repo::RepoCommandParameter(wire));
 
-  RepoCommandParameter decoded(wire);
+  repo::RepoCommandParameter decoded(wire);
   //std::cout << decoded << std::endl;
   BOOST_CHECK_EQUAL(decoded.getName(), parameter.getName());
   BOOST_CHECK_EQUAL(decoded.getStartBlockId(), parameter.getStartBlockId());
@@ -54,4 +55,5 @@
 
 BOOST_AUTO_TEST_SUITE_END()
 
+} // namespace tests
 } // namespace repo
diff --git a/tests/test-repo-command-response.cpp b/tests/repo-command-response.cpp
similarity index 86%
rename from tests/test-repo-command-response.cpp
rename to tests/repo-command-response.cpp
index c97fce8..f9d5226 100644
--- a/tests/test-repo-command-response.cpp
+++ b/tests/repo-command-response.cpp
@@ -9,12 +9,13 @@
 #include <boost/test/unit_test.hpp>
 
 namespace repo {
+namespace tests {
 
-BOOST_AUTO_TEST_SUITE(TestRepoCommandResponse)
+BOOST_AUTO_TEST_SUITE(RepoCommandResponse)
 
-BOOST_AUTO_TEST_CASE(TestRepoCommandResponse)
+BOOST_AUTO_TEST_CASE(EncodeDecode)
 {
-  RepoCommandResponse response;
+  repo::RepoCommandResponse response;
   response.setStatusCode(404);
   response.setStartBlockId(1);
   response.setEndBlockId(100);
@@ -38,9 +39,9 @@
   BOOST_REQUIRE_EQUAL_COLLECTIONS(expected, expected + sizeof(expected),
                                   wire.begin(), wire.end());
 
-  BOOST_REQUIRE_NO_THROW(RepoCommandResponse(wire));
+  BOOST_REQUIRE_NO_THROW(repo::RepoCommandResponse(wire));
 
-  RepoCommandResponse decoded(wire);
+  repo::RepoCommandResponse decoded(wire);
   BOOST_CHECK_EQUAL(decoded.getStatusCode(), response.getStatusCode());
   BOOST_CHECK_EQUAL(decoded.getStartBlockId(), response.getStartBlockId());
   BOOST_CHECK_EQUAL(decoded.getEndBlockId(), response.getEndBlockId());
@@ -51,4 +52,5 @@
 
 BOOST_AUTO_TEST_SUITE_END()
 
+} // namespace tests
 } // namespace repo
diff --git a/tests/sqlite-fixture.hpp b/tests/sqlite-fixture.hpp
new file mode 100644
index 0000000..b370f20
--- /dev/null
+++ b/tests/sqlite-fixture.hpp
@@ -0,0 +1,46 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#ifndef REPO_TESTS_SQLITE_FIXTURE_HPP
+#define REPO_TESTS_SQLITE_FIXTURE_HPP
+
+#include "../storage/sqlite/sqlite-handle.hpp"
+
+#include <boost/filesystem.hpp>
+#include <boost/test/unit_test.hpp>
+
+namespace repo {
+namespace tests {
+
+class SqliteFixture
+{
+public:
+  SqliteFixture()
+  {
+    boost::filesystem::path testPath("unittestdb");
+    boost::filesystem::file_status testPathStatus = boost::filesystem::status(testPath);
+    if (!boost::filesystem::is_directory(testPathStatus)) {
+      if (!boost::filesystem::create_directory(boost::filesystem::path(testPath))) {
+        BOOST_FAIL("Cannot create unittestdb folder");
+      }
+    }
+    handle = new SqliteHandle("unittestdb");
+  }
+
+  ~SqliteFixture()
+  {
+    delete handle;
+    boost::filesystem::remove_all(boost::filesystem::path("unittestdb"));
+  }
+
+public:
+  SqliteHandle* handle;
+};
+
+} // namespace tests
+} // namespace repo
+
+#endif // REPO_TESTS_SQLITE_FIXTURE_HPP
diff --git a/tests/sqlite-handle.cpp b/tests/sqlite-handle.cpp
new file mode 100644
index 0000000..5f3ef22
--- /dev/null
+++ b/tests/sqlite-handle.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "../storage/sqlite/sqlite-handle.hpp"
+
+#include "sqlite-fixture.hpp"
+#include "dataset-fixtures.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace repo {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(SqliteHandle)
+
+template<class Dataset>
+class Fixture : public SqliteFixture, public Dataset
+{
+};
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertReadDelete, T, DatasetFixtures, Fixture<T>)
+{
+  BOOST_TEST_MESSAGE(T::getName());
+
+  // Insert
+  for (typename T::DataContainer::iterator i = this->data.begin();
+       i != this->data.end(); ++i) {
+    BOOST_CHECK_EQUAL(this->handle->insertData(**i), true);
+  }
+
+  BOOST_CHECK_EQUAL(this->handle->size(), this->data.size());
+
+  // Read (all items should exist)
+  for (typename T::InterestContainer::iterator i = this->interests.begin();
+       i != this->interests.end(); ++i) {
+    ndn::Data retrievedData;
+    BOOST_REQUIRE_EQUAL(this->handle->readData(i->first, retrievedData), true);
+    BOOST_CHECK_EQUAL(retrievedData, *i->second);
+  }
+
+  // Delete
+  for (typename T::DataContainer::iterator i = this->data.begin();
+       i != this->data.end(); ++i) {
+    BOOST_CHECK_EQUAL(this->handle->deleteData((*i)->getName()), true);
+  }
+
+  // Read (none of the items should exist)
+  for (typename T::InterestContainer::iterator i = this->interests.begin();
+       i != this->interests.end(); ++i) {
+    ndn::Data retrievedData;
+    BOOST_REQUIRE_EQUAL(this->handle->readData(i->first, retrievedData), false);
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace repo
diff --git a/tests/tcp-bulk-insert-handle.cpp b/tests/tcp-bulk-insert-handle.cpp
new file mode 100644
index 0000000..ffe002b
--- /dev/null
+++ b/tests/tcp-bulk-insert-handle.cpp
@@ -0,0 +1,172 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (C) 2014 Regents of the University of California.
+ * See COPYING for copyright and distribution information.
+ */
+
+#include "../ndn-handle/tcp-bulk-insert-handle.hpp"
+
+#include "sqlite-fixture.hpp"
+#include "dataset-fixtures.hpp"
+
+#include <boost/test/unit_test.hpp>
+
+namespace repo {
+namespace tests {
+
+BOOST_AUTO_TEST_SUITE(TcpBulkInsertHandle)
+
+class TcpClient
+{
+public:
+  TcpClient()
+    : socket(ioService)
+  {
+  }
+
+  void
+  start(const std::string& host, const std::string& port)
+  {
+    using namespace boost::asio;
+
+    ip::tcp::resolver resolver(ioService);
+    ip::tcp::resolver::query query(host, port);
+
+    ip::tcp::resolver::iterator endpoint = resolver.resolve(query);
+    ip::tcp::resolver::iterator end;
+
+    if (endpoint == end)
+      BOOST_FAIL("Cannot resolve [" + host + ":" + port + "]");
+
+    ip::tcp::endpoint serverEndpoint = *endpoint;
+
+    socket.async_connect(serverEndpoint,
+                         bind(&TcpClient::onSuccessfullConnect, this, _1));
+  }
+
+  virtual void
+  onSuccessfullConnect(const boost::system::error_code& error)
+  {
+    if (error)
+      {
+        BOOST_FAIL("TCP connection aborted");
+        return;
+      }
+  }
+
+public:
+  boost::asio::io_service ioService;
+  boost::asio::ip::tcp::socket socket;
+};
+
+template<class Dataset>
+class TcpBulkInsertFixture : public TcpClient,
+                             public SqliteFixture,
+                             public Dataset
+{
+public:
+  TcpBulkInsertFixture()
+    : scheduler(ioService)
+    , bulkInserter(ioService, *handle)
+  {
+    guardEvent = scheduler.scheduleEvent(ndn::time::seconds(2),
+                                         bind(&TcpBulkInsertFixture::fail, this, "Test timed out"));
+  }
+
+  virtual void
+  onSuccessfullConnect(const boost::system::error_code& error)
+  {
+    TcpClient::onSuccessfullConnect(error);
+
+    // This value may need to be adjusted if some dataset exceeds 100k
+    socket.set_option(boost::asio::socket_base::send_buffer_size(100000));
+
+    // Initially I wrote the following to use scatter-gather approach (using
+    // std::vector<const_buffer> and a single socket.async_send operation). Unfortunately, as
+    // described in http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/overview/implementation.html,
+    // scatter-gather is limited to at most `min(64,IOV_MAX)` buffers to be transmitted
+    // in a single operation
+    for (typename Dataset::DataContainer::iterator i = this->data.begin();
+         i != this->data.end(); ++i) {
+
+      socket.async_send(boost::asio::buffer((*i)->wireEncode().wire(),  (*i)->wireEncode().size()),
+                        bind(&TcpBulkInsertFixture::onSendFinished, this, _1, false));
+    }
+
+    socket.async_send(boost::asio::buffer(static_cast<const uint8_t*>(0), 0),
+                      bind(&TcpBulkInsertFixture::onSendFinished, this, _1, true));
+  }
+
+  void
+  onSendFinished(const boost::system::error_code& error, bool isFinal)
+  {
+    if (error) {
+      BOOST_FAIL("TCP connection aborted");
+      return;
+    }
+
+    if (isFinal) {
+      scheduler.cancelEvent(guardEvent);
+
+      // In case there are some outstanding handlers
+      // ioService.post(bind(&TcpBulkInsertFixture::stop, this));
+      scheduler.scheduleEvent(ndn::time::seconds(1),
+                              bind(&TcpBulkInsertFixture::stop, this));
+    }
+  }
+
+  void
+  fail(const std::string& info)
+  {
+    ioService.stop();
+    BOOST_FAIL(info);
+  }
+
+  void
+  stop()
+  {
+    // Terminate test
+    socket.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
+    socket.close();
+
+    bulkInserter.stop();
+    // may be ioService.stop() as well
+  }
+
+public:
+  Scheduler scheduler;
+  ndn::EventId guardEvent;
+  repo::TcpBulkInsertHandle bulkInserter;
+};
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(BulkInsertAndRead, T, DatasetFixtures, TcpBulkInsertFixture<T>)
+{
+  BOOST_TEST_MESSAGE(T::getName());
+  // BOOST_CHECK_EQUAL(this->handle->size(), 1);
+
+  // start bulk inserter
+  this->bulkInserter.listen("localhost", "17376");
+
+  // start test
+  this->start("localhost", "17376");
+
+  // actually run the test
+  this->ioService.run();
+
+  BOOST_CHECK_EQUAL(this->handle->size(), this->data.size());
+
+  // Read (all items should exist)
+  for (typename T::InterestContainer::iterator i = this->interests.begin();
+       i != this->interests.end(); ++i) {
+    ndn::Data retrievedData;
+    BOOST_REQUIRE_EQUAL(this->handle->readData(i->first, retrievedData), true);
+    BOOST_CHECK_EQUAL(retrievedData, *i->second);
+  }
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace repo
+} // namespace tests
diff --git a/tests/test-sqlite.cpp b/tests/test-sqlite.cpp
deleted file mode 100644
index 1d9793c..0000000
--- a/tests/test-sqlite.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (C) 2014 Regents of the University of California.
- * See COPYING for copyright and distribution information.
- */
-
-#include "../storage/sqlite/sqlite-handle.hpp"
-
-#include <ndn-cpp-dev/security/key-chain.hpp>
-
-#include <boost/filesystem.hpp>
-#include <boost/test/unit_test.hpp>
-#include <boost/test/output_test_stream.hpp>
-
-namespace repo {
-
-class TestDbCreateDestroy
-{
-public:
-  TestDbCreateDestroy()
-  {
-    boost::filesystem::path testPath("unittestdb");
-    boost::filesystem::file_status testPathStatus = boost::filesystem::status(testPath);
-    if (!boost::filesystem::is_directory(testPathStatus)) {
-      if (!boost::filesystem::create_directory(boost::filesystem::path(testPath))) {
-        BOOST_FAIL("Cannot create unittestdb folder");
-      }
-    }
-    handle = new SqliteHandle("unittestdb");
-  }
-
-  ~TestDbCreateDestroy()
-  {
-    delete handle;
-    boost::filesystem::remove_all(boost::filesystem::path("unittestdb"));
-  }
-
-public:
-  SqliteHandle* handle;
-};
-
-BOOST_FIXTURE_TEST_SUITE(TestSqlite, TestDbCreateDestroy)
-
-static inline ndn::shared_ptr<ndn::Data>
-createData(const ndn::Name& name)
-{
-  static ndn::KeyChain keyChain;
-  static std::vector<uint8_t> content(1500, '-');
-
-  ndn::shared_ptr<ndn::Data> data = ndn::make_shared<ndn::Data>();
-  data->setName(name);
-  data->setContent(&content[0], content.size());
-  keyChain.sign(*data);
-
-  return data;
-}
-
-class FixtureBase : public TestDbCreateDestroy
-{
-public:
-  typedef std::list<ndn::shared_ptr<ndn::Data> > DataContainer;
-  DataContainer datas;
-
-  typedef std::list<std::pair<ndn::Interest, ndn::shared_ptr<ndn::Data> > > InterestContainer;
-  InterestContainer interests;
-};
-
-template<size_t N>
-class BaseSmoketestFixture : public FixtureBase
-{
-public:
-  BaseSmoketestFixture()
-  {
-    ndn::Name baseName("/x/y/z/test/1");
-    for (size_t i = 0; i < N; i++) {
-      ndn::Name name(baseName);
-      name.appendSegment(i);
-      ndn::shared_ptr<Data> data = createData(name);
-      this->datas.push_back(data);
-
-      this->interests.push_back(std::make_pair(Interest(name), data));
-    }
-  }
-};
-
-class BaseTestFixture : public FixtureBase
-{
-public:
-  BaseTestFixture()
-  {
-    datas.push_back(createData("/a"));
-    interests.push_back(std::make_pair(Interest("/a"), datas.back()));
-
-    datas.push_back(createData("/a/b"));
-    interests.push_back(std::make_pair(Interest("/a/b"), datas.back()));
-
-    datas.push_back(createData("/a/b/c"));
-    interests.push_back(std::make_pair(Interest("/a/b/c"), datas.back()));
-
-    datas.push_back(createData("/a/b/c/d"));
-    interests.push_back(std::make_pair(Interest("/a/b/c/d"), datas.back()));
-  }
-};
-
-class SelectorTestFixture : public FixtureBase
-{
-public:
-  SelectorTestFixture()
-  {
-    datas.push_back(createData("/a/1"));
-    datas.push_back(createData("/b/1"));
-    interests.push_back(std::make_pair(Interest()
-                                         .setName("/b")
-                                         .setSelectors(Selectors()
-                                                         .setChildSelector(0)),
-                                       datas.back()));
-
-    datas.push_back(createData("/c/1"));
-    datas.push_back(createData("/b/99"));
-    interests.push_back(std::make_pair(Interest()
-                                         .setName("/b")
-                                         .setSelectors(Selectors()
-                                                         .setChildSelector(1)),
-                                       datas.back()));
-    datas.push_back(createData("/b/5"));
-    datas.push_back(createData("/b/55"));
-  }
-};
-
-typedef boost::mpl::vector< BaseTestFixture,
-                            SelectorTestFixture,
-                            BaseSmoketestFixture<1>,
-                            BaseSmoketestFixture<100> > Fixtures;
-
-BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertReadDelete, T, Fixtures, T)
-{
-  // Insert
-  for (typename T::DataContainer::iterator i = this->datas.begin();
-       i != this->datas.end(); ++i) {
-    BOOST_CHECK_EQUAL(this->handle->insertData(**i), true);
-  }
-
-  // Read (all items should exist)
-  for (typename T::InterestContainer::iterator i = this->interests.begin();
-       i != this->interests.end(); ++i) {
-    ndn::Data retrievedData;
-    BOOST_REQUIRE_EQUAL(this->handle->readData(i->first, retrievedData), true);
-    BOOST_CHECK_EQUAL(retrievedData, *i->second);
-  }
-
-  // Delete
-  for (typename T::DataContainer::iterator i = this->datas.begin();
-       i != this->datas.end(); ++i) {
-    BOOST_CHECK_EQUAL(this->handle->deleteData((*i)->getName()), true);
-  }
-
-  // Read (none of the items should exist)
-  for (typename T::InterestContainer::iterator i = this->interests.begin();
-       i != this->interests.end(); ++i) {
-    ndn::Data retrievedData;
-    BOOST_REQUIRE_EQUAL(this->handle->readData(i->first, retrievedData), false);
-  }
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-}// namespace repo