diff --git a/tests/integrated/README.md b/tests/integrated/README.md
new file mode 100644
index 0000000..f2ad333
--- /dev/null
+++ b/tests/integrated/README.md
@@ -0,0 +1,10 @@
+Running integrated tests
+========================
+
+In order to run integrated tests, NFD (nfd and nrd) should be running.
+
+Suggested command sequence:
+
+    nfd-start
+    ./build/integrated-tests
+    nfd-stop
diff --git a/tests/integrated/test-basic-command-insert-delete.cpp b/tests/integrated/test-basic-command-insert-delete.cpp
new file mode 100644
index 0000000..3f2992f
--- /dev/null
+++ b/tests/integrated/test-basic-command-insert-delete.cpp
@@ -0,0 +1,300 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng 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.
+ *
+ * repo-ng 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
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "handles/write-handle.hpp"
+#include "handles/delete-handle.hpp"
+#include "storage/storage-handle.hpp"
+#include "storage/sqlite-handle.hpp"
+
+#include "../sqlite-fixture.hpp"
+#include "../dataset-fixtures.hpp"
+
+#include <ndn-cxx/util/command-interest-generator.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+namespace repo {
+namespace tests {
+
+using ndn::time::milliseconds;
+using ndn::time::seconds;
+using ndn::EventId;
+namespace random=ndn::random;
+
+//All the test cases in this test suite should be run at once.
+BOOST_AUTO_TEST_SUITE(TestBasicCommandInsertDelete)
+
+const static uint8_t content[8] = {3, 1, 4, 1, 5, 9, 2, 6};
+
+template<class Dataset>
+class Fixture : public SqliteFixture, public Dataset
+{
+public:
+  Fixture()
+    : scheduler(repoFace.getIoService())
+    , writeHandle(repoFace, *handle, keyChain, scheduler, validator)
+    , deleteHandle(repoFace, *handle, keyChain, scheduler, validator)
+    , insertFace(repoFace.getIoService())
+    , deleteFace(repoFace.getIoService())
+  {
+    validator.addInterestRule("^<>",
+                              *keyChain.getCertificate(keyChain.getDefaultCertificateName()));
+    writeHandle.listen(Name("/repo/command"));
+    deleteHandle.listen(Name("/repo/command"));
+  }
+
+  ~Fixture()
+  {
+    repoFace.getIoService().stop();
+  }
+
+  void
+  scheduleInsertEvent();
+
+  void
+  scheduleDeleteEvent();
+
+  void
+  onInsertInterest(const Interest& interest);
+
+  void
+  onRegisterFailed(const std::string& reason);
+
+  void
+  delayedInterest();
+
+  void
+  stopFaceProcess();
+
+
+  void
+  onInsertData(const Interest& interest, Data& data);
+
+  void
+  onDeleteData(const Interest& interest, Data& data);
+
+  void
+  onInsertTimeout(const Interest& interest);
+
+  void
+  onDeleteTimeout(const Interest& interest);
+
+  void
+  sendInsertInterest(const Interest& interest);
+
+  void
+  sendDeleteInterest(const Interest& deleteInterest);
+
+  void
+  checkInsertOK(const Interest& interest);
+
+  void
+  checkDeleteOK(const Interest& interest);
+
+public:
+  Face repoFace;
+  Scheduler scheduler;
+  CommandInterestValidator validator;
+  KeyChain keyChain;
+  ndn::CommandInterestGenerator generator;
+  WriteHandle writeHandle;
+  DeleteHandle deleteHandle;
+  Face insertFace;
+  Face deleteFace;
+  std::map<Name, EventId> insertEvents;
+};
+
+template<class T> void
+Fixture<T>::onInsertInterest(const Interest& interest)
+{
+  Data data(Name(interest.getName()));
+  data.setContent(content, sizeof(content));
+  data.setFreshnessPeriod(milliseconds(0));
+  keyChain.sign(data);
+  insertFace.put(data);
+
+  std::map<Name, EventId>::iterator event = insertEvents.find(interest.getName());
+  if (event != insertEvents.end()) {
+    scheduler.cancelEvent(event->second);
+    insertEvents.erase(event);
+  }
+  // schedule an event 50ms later to check whether insert is OK
+  scheduler.scheduleEvent(milliseconds(50),
+                          bind(&Fixture<T>::checkInsertOK, this, interest));
+
+}
+
+
+template<class T> void
+Fixture<T>::onRegisterFailed(const std::string& reason)
+{
+  BOOST_ERROR("ERROR: Failed to register prefix in local hub's daemon" + reason);
+}
+
+template<class T> void
+Fixture<T>::delayedInterest()
+{
+  BOOST_ERROR("Fetching interest does not come. It may be satisfied in CS or something is wrong");
+}
+
+template<class T> void
+Fixture<T>::stopFaceProcess()
+{
+  repoFace.getIoService().stop();
+}
+
+template<class T> void
+Fixture<T>::onInsertData(const Interest& interest, Data& data)
+{
+  RepoCommandResponse response;
+  response.wireDecode(data.getContent().blockFromValue());
+  int statusCode = response.getStatusCode();
+  BOOST_CHECK_EQUAL(statusCode, 100);
+}
+
+template<class T> void
+Fixture<T>::onDeleteData(const Interest& interest, Data& data)
+{
+  RepoCommandResponse response;
+  response.wireDecode(data.getContent().blockFromValue());
+  int statusCode = response.getStatusCode();
+  BOOST_CHECK_EQUAL(statusCode, 200);
+
+  //schedlute an event to check whether delete is OK.
+  scheduler.scheduleEvent(milliseconds(100),
+                          bind(&Fixture<T>::checkDeleteOK, this, interest));
+}
+
+template<class T> void
+Fixture<T>::onInsertTimeout(const Interest& interest)
+{
+  BOOST_ERROR("Inserert command timeout");
+}
+
+template<class T> void
+Fixture<T>::onDeleteTimeout(const Interest& interest)
+{
+  BOOST_ERROR("delete command timeout");
+}
+
+template<class T> void
+Fixture<T>::sendInsertInterest(const Interest& insertInterest)
+{
+  insertFace.expressInterest(insertInterest,
+                             bind(&Fixture<T>::onInsertData, this, _1, _2),
+                             bind(&Fixture<T>::onInsertTimeout, this, _1));
+}
+
+template<class T> void
+Fixture<T>::sendDeleteInterest(const Interest& deleteInterest)
+{
+  deleteFace.expressInterest(deleteInterest,
+                             bind(&Fixture<T>::onDeleteData, this, _1, _2),
+                             bind(&Fixture<T>::onDeleteTimeout, this, _1));
+}
+
+template<class T> void
+Fixture<T>::checkInsertOK(const Interest& interest)
+{
+  Data data;
+  BOOST_TEST_MESSAGE(interest);
+  BOOST_CHECK_EQUAL(handle->readData(interest, data), true);
+  int rc = memcmp(data.getContent().value(), content, sizeof(content));
+  BOOST_CHECK_EQUAL(rc, 0);
+}
+
+template<class T> void
+Fixture<T>::checkDeleteOK(const Interest& interest)
+{
+  Data data;
+  BOOST_CHECK_EQUAL(handle->readData(interest, data), false);
+}
+
+
+template<class T> void
+Fixture<T>::scheduleInsertEvent()
+{
+  int timeCount = 1;
+  for (typename T::DataContainer::iterator i = this->data.begin();
+       i != this->data.end(); ++i) {
+    Name insertCommandName("/repo/command/insert");
+    RepoCommandParameter insertParameter;
+    insertParameter.setName(Name((*i)->getName())
+                              .appendNumber(random::generateWord64()));
+
+    insertCommandName.append(insertParameter.wireEncode());
+    Interest insertInterest(insertCommandName);
+    generator.generateWithIdentity(insertInterest, keyChain.getDefaultIdentity());
+    //schedule a job to express insertInterest every 50ms
+    scheduler.scheduleEvent(milliseconds(timeCount * 50 + 1000),
+                            bind(&Fixture<T>::sendInsertInterest, this, insertInterest));
+    //schedule what to do when interest timeout
+
+    EventId delayEventId = scheduler.scheduleEvent(milliseconds(5000 + timeCount * 50),
+                                                   bind(&Fixture<T>::delayedInterest, this));
+    insertEvents[insertParameter.getName()] = delayEventId;
+
+    //The delayEvent will be canceled in onInsertInterest
+    insertFace.setInterestFilter(insertParameter.getName(),
+                                 bind(&Fixture<T>::onInsertInterest, this, _2),
+                                 bind(&Fixture<T>::onRegisterFailed, this, _2));
+    timeCount++;
+  }
+}
+
+
+template<class T> void
+Fixture<T>::scheduleDeleteEvent()
+{
+  int timeCount = 1;
+  for (typename T::DataContainer::iterator i = this->data.begin();
+       i != this->data.end(); ++i) {
+    Name deleteCommandName("/repo/command/delete");
+    RepoCommandParameter deleteParameter;
+    static boost::random::mt19937_64 gen;
+    static boost::random::uniform_int_distribution<uint64_t> dist(0, 0xFFFFFFFFFFFFFFFFLL);
+    deleteParameter.setProcessId(dist(gen));
+    deleteParameter.setName((*i)->getName());
+    deleteCommandName.append(deleteParameter.wireEncode());
+    Interest deleteInterest(deleteCommandName);
+    generator.generateWithIdentity(deleteInterest, keyChain.getDefaultIdentity());
+    scheduler.scheduleEvent(milliseconds(4000 + timeCount * 50),
+                            bind(&Fixture<T>::sendDeleteInterest, this, deleteInterest));
+    timeCount++;
+  }
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(InsertDelete, T, DatasetFixtures, Fixture<T>)
+{
+  // schedule events
+  this->scheduler.scheduleEvent(seconds(0),
+                                bind(&Fixture<T>::scheduleInsertEvent, this));
+  this->scheduler.scheduleEvent(seconds(10),
+                                bind(&Fixture<T>::scheduleDeleteEvent, this));
+
+  // schedule an event to terminate IO
+  this->scheduler.scheduleEvent(seconds(20),
+                                bind(&Fixture<T>::stopFaceProcess, this));
+  this->repoFace.getIoService().run();
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} //namespace tests
+} //namespace repo
diff --git a/tests/integrated/test-basic-interest-read.cpp b/tests/integrated/test-basic-interest-read.cpp
new file mode 100644
index 0000000..0ab2346
--- /dev/null
+++ b/tests/integrated/test-basic-interest-read.cpp
@@ -0,0 +1,146 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014,  Regents of the University of California.
+ *
+ * This file is part of NDN repo-ng (Next generation of NDN repository).
+ * See AUTHORS.md for complete list of repo-ng authors and contributors.
+ *
+ * repo-ng 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.
+ *
+ * repo-ng 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
+ * repo-ng, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "handles/read-handle.hpp"
+#include "storage/storage-handle.hpp"
+#include "storage/sqlite-handle.hpp"
+
+#include "../sqlite-fixture.hpp"
+#include "../dataset-fixtures.hpp"
+
+#include <ndn-cxx/util/random.hpp>
+
+#include <boost/test/unit_test.hpp>
+
+namespace repo {
+namespace tests {
+
+//All the test cases in this test suite should be run at once.
+BOOST_AUTO_TEST_SUITE(TestBasicInerestRead)
+
+const static uint8_t content[8] = {3, 1, 4, 1, 5, 9, 2, 6};
+
+template<class Dataset>
+class BasicInterestReadFixture : public SqliteFixture, public Dataset
+{
+public:
+  BasicInterestReadFixture()
+    : scheduler(repoFace.getIoService())
+    , readHandle(repoFace, *handle, keyChain, scheduler)
+    , readFace(repoFace.getIoService())
+  {
+  }
+
+  ~BasicInterestReadFixture()
+  {
+    repoFace.getIoService().stop();
+  }
+
+  void
+  startListen()
+  {
+    readHandle.listen("/");
+  }
+
+  void
+  scheduleReadEvent()
+  {
+    int timeCount = 1;
+    for (typename Dataset::DataContainer::iterator i = this->data.begin();
+         i != this->data.end(); ++i) {
+      //First insert a data into database;
+      (*i)->setContent(content, sizeof(content));
+      (*i)->setFreshnessPeriod(ndn::time::milliseconds(36000));
+      keyChain.sign(**i);
+      bool rc = handle->insertData(**i);
+
+      BOOST_CHECK_EQUAL(rc, true);
+
+      Interest readInterest((*i)->getName());
+      readInterest.setMustBeFresh(true);
+      scheduler.scheduleEvent(ndn::time::milliseconds(timeCount * 50),
+                              ndn::bind(&BasicInterestReadFixture<Dataset>::sendInterest, this,
+                                        readInterest));
+      timeCount++;
+    }
+  }
+
+  void
+  stopFaceProcess()
+  {
+    repoFace.getIoService().stop();
+  }
+
+  void
+  onReadData(const ndn::Interest& interest, ndn::Data& data)
+  {
+    int rc = memcmp(data.getContent().value(), content, sizeof(content));
+    BOOST_CHECK_EQUAL(rc, 0);
+    //then delete the data
+    BOOST_CHECK_EQUAL(handle->deleteData(data.getName()), true);
+  }
+
+  void
+  onReadTimeout(const ndn::Interest& interest)
+  {
+    BOOST_ERROR("Insert not successfull or Read data does not successfull");
+  }
+
+  void
+  sendInterest(const ndn::Interest& interest)
+  {
+    readFace.expressInterest(interest,
+                             bind(&BasicInterestReadFixture::onReadData, this, _1, _2),
+                             bind(&BasicInterestReadFixture::onReadTimeout, this, _1));
+  }
+
+public:
+  ndn::Face repoFace;
+  ndn::KeyChain keyChain;
+  ndn::Scheduler scheduler;
+  ReadHandle readHandle;
+  ndn::Face readFace;
+};
+
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Read, T, DatasetFixtures, BasicInterestReadFixture<T>)
+{
+  // Insert dataset
+  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());
+
+  this->startListen();
+  this->scheduler.scheduleEvent(ndn::time::seconds(0),
+                                ndn::bind(&BasicInterestReadFixture<T>::scheduleReadEvent, this));
+
+  // schedule an event to terminate IO
+  this->scheduler.scheduleEvent(ndn::time::seconds(10),
+                                ndn::bind(&BasicInterestReadFixture<T>::stopFaceProcess, this));
+  this->repoFace.getIoService().run();
+
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} //namespace tests
+} //namespace repo
