diff --git a/tests/pib/pib-db.t.cpp b/tests/pib/pib-db.t.cpp
new file mode 100644
index 0000000..6d826d2
--- /dev/null
+++ b/tests/pib/pib-db.t.cpp
@@ -0,0 +1,474 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2015 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ */
+
+#include "tools/pib/pib-db.hpp"
+#include "identity-management-time-fixture.hpp"
+
+#include <boost/filesystem.hpp>
+
+#include "tests/test-common.hpp"
+
+namespace ndn {
+namespace pib {
+namespace tests {
+
+class PibDbTestFixture : public ndn::security::IdentityManagementTimeFixture
+{
+public:
+  PibDbTestFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH) / "DbTest")
+    , db(tmpPath.c_str())
+  {
+  }
+
+  ~PibDbTestFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+  boost::asio::io_service io;
+  boost::filesystem::path tmpPath;
+  PibDb db;
+  std::vector<Name> deletedIds;
+  std::vector<Name> deletedKeys;
+  std::vector<Name> deletedCerts;
+  std::vector<Name> insertedCerts;
+};
+
+
+BOOST_FIXTURE_TEST_SUITE(TestPibDb, PibDbTestFixture)
+
+BOOST_AUTO_TEST_CASE(MgmtTest)
+{
+  Name testUser("/localhost/pib/test/mgmt");
+  addIdentity(testUser);
+  Name testUserCertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser);
+  shared_ptr<IdentityCertificate> testUserCert = m_keyChain.getCertificate(testUserCertName);
+
+
+  BOOST_CHECK_EQUAL(db.getOwnerName(), "");
+  BOOST_CHECK(db.getMgmtCertificate() == nullptr);
+
+  db.updateMgmtCertificate(*testUserCert);
+  BOOST_CHECK_EQUAL(db.getOwnerName(), "test");
+  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
+  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(), testUserCertName);
+
+  db.setTpmLocator("tpmLocator");
+  BOOST_CHECK_EQUAL(db.getTpmLocator(), "tpmLocator");
+
+  Name testUser2("/localhost/pib/test2/mgmt");
+  addIdentity(testUser2);
+  Name testUser2CertName = m_keyChain.getDefaultCertificateNameForIdentity(testUser2);
+  shared_ptr<IdentityCertificate> testUser2Cert = m_keyChain.getCertificate(testUser2CertName);
+
+  BOOST_CHECK_THROW(db.updateMgmtCertificate(*testUser2Cert), PibDb::Error);
+
+  Name testUserKeyName2 = m_keyChain.generateRsaKeyPairAsDefault(testUser);
+  shared_ptr<IdentityCertificate> testUserCert2 = m_keyChain.selfSign(testUserKeyName2);
+
+  BOOST_CHECK_NO_THROW(db.updateMgmtCertificate(*testUserCert2));
+  BOOST_REQUIRE(db.getMgmtCertificate() != nullptr);
+  BOOST_CHECK_EQUAL(db.getMgmtCertificate()->getName(),
+                    testUserCert2->getName());
+}
+
+BOOST_AUTO_TEST_CASE(IdentityTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  Name identity("/test/identity");
+  Name identity2("/test/identity2");
+
+  // Add an identity: /test/identity
+  // Since there is no default identity,
+  // the new added identity will be set as the default identity.
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
+  db.addIdentity(identity);
+  BOOST_CHECK(db.hasIdentity(identity));
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
+
+  // Add the second identity: /test/identity2
+  // Since the default identity exists,
+  // the new added identity will not be set as the default identity.
+  db.addIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity);
+
+  // Set the second identity: /test/identity2 as default explicitly
+  db.setDefaultIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
+
+  // Delete identity /test/identity2, which is also the default one
+  // This will trigger the identityDeleted signal
+  // and also causes no default identity.
+  db.deleteIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), true);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), PibDb::NON_EXISTING_IDENTITY);
+  deletedIds.clear();
+
+  // Add the second identity back
+  // Since there is no default identity (though another identity still exists),
+  // the second identity will be set as default.
+  db.addIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), identity2);
+
+  // Delete identity /test/identity
+  db.deleteIdentity(identity);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), true);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity);
+  deletedIds.clear();
+
+  // Delete identity /test/identity2
+  db.deleteIdentity(identity2);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(identity2), false);
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], identity2);
+  deletedIds.clear();
+}
+
+
+BOOST_AUTO_TEST_CASE(KeyTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  db.keyDeleted.connect([this] (const Name& key) {
+      this->deletedKeys.push_back(key);
+    });
+
+  // Initialize id1
+  Name id1("/test/identity");
+  addIdentity(id1);
+  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
+  Name keyName11 = cert111->getPublicKeyName();
+  PublicKey& key11 = cert111->getPublicKeyInfo();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
+  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
+  PublicKey& key12 = cert121->getPublicKeyInfo();
+
+  // Initialize id2
+  advanceClocks(io, time::milliseconds(100));
+  Name id2("/test/identity2");
+  addIdentity(id2);
+  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
+  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
+  Name keyName21 = cert211->getPublicKeyName();
+  PublicKey& key21 = cert211->getPublicKeyInfo();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
+  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
+  PublicKey& key22 = cert221->getPublicKeyInfo();
+
+  // Add a key, the corresponding identity should be added as well
+  // Since the PIB does not have any default identity set before,
+  // the added identity will be set as default.
+  // Since there is no default key for the identity,
+  // the added key will be set as default.
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
+  BOOST_CHECK(db.getKey(keyName11) == nullptr);
+  db.addKey(keyName11, key11);
+  BOOST_CHECK(db.hasIdentity(id1));
+  BOOST_CHECK(db.getKey(keyName11) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+
+  // Add the second key of /test/identity.
+  // Since the default key of /test/identity has been set,
+  // The new added key will not be set as default.
+  db.addKey(keyName12, key12);
+  BOOST_CHECK(db.getKey(keyName12) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+
+  // Explicitly set the second key as the default key of /test/identity
+  db.setDefaultKeyNameOfIdentity(keyName12);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
+
+  // Delete the second key which is also the default key.
+  // This will trigger the keyDeleted signal.
+  // This will also cause no default key for /test/identity
+  db.deleteKey(keyName12);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), false);
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
+  BOOST_CHECK_EQUAL(deletedKeys[0], keyName12);
+  deletedKeys.clear();
+
+  // Add the second key back.
+  // Since there is no default key of /test/identity (although another key still exists)
+  // The second key will be set as the default key of /test/identity
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), PibDb::NON_EXISTING_KEY);
+  db.addKey(keyName12, key12);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName12);
+
+  // Prepare test for identity deletion
+  db.addKey(keyName21, key21);
+  db.addKey(keyName22, key22);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+
+  // Delete the identity.
+  // All keys of the identity should also be deleted,
+  // and the keyDeleted signal should be triggered twice.
+  db.deleteIdentity(id1);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
+              deletedKeys.end());
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
+              deletedKeys.end());
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], id1);
+}
+
+BOOST_AUTO_TEST_CASE(CertTest)
+{
+  db.identityDeleted.connect([this] (const Name& id) {
+      this->deletedIds.push_back(id);
+    });
+
+  db.keyDeleted.connect([this] (const Name& key) {
+      this->deletedKeys.push_back(key);
+    });
+
+  db.certificateDeleted.connect([this] (const Name& certificate) {
+      this->deletedCerts.push_back(certificate);
+    });
+
+  db.certificateInserted.connect([this] (const Name& certificate) {
+      this->insertedCerts.push_back(certificate);
+    });
+
+  // Initialize id1
+  Name id1("/test/identity");
+  addIdentity(id1);
+  Name certName111 = m_keyChain.getDefaultCertificateNameForIdentity(id1);
+  shared_ptr<IdentityCertificate> cert111 = m_keyChain.getCertificate(certName111);
+  Name keyName11 = cert111->getPublicKeyName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert112 = m_keyChain.selfSign(keyName11);
+  Name certName112 = cert112->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName12 = m_keyChain.generateRsaKeyPairAsDefault(id1);
+  shared_ptr<IdentityCertificate> cert121 = m_keyChain.selfSign(keyName12);
+  Name certName121 = cert121->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert122 = m_keyChain.selfSign(keyName12);
+  Name certName122 = cert122->getName();
+
+  // Initialize id2
+  advanceClocks(io, time::milliseconds(100));
+  Name id2("/test/identity2");
+  addIdentity(id2);
+  Name certName211 = m_keyChain.getDefaultCertificateNameForIdentity(id2);
+  shared_ptr<IdentityCertificate> cert211 = m_keyChain.getCertificate(certName211);
+  Name keyName21 = cert211->getPublicKeyName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert212 = m_keyChain.selfSign(keyName21);
+  Name certName212 = cert212->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  Name keyName22 = m_keyChain.generateRsaKeyPairAsDefault(id2);
+  shared_ptr<IdentityCertificate> cert221 = m_keyChain.selfSign(keyName22);
+  Name certName221 = cert221->getName();
+
+  advanceClocks(io, time::milliseconds(100));
+  shared_ptr<IdentityCertificate> cert222 = m_keyChain.selfSign(keyName22);
+  Name certName222 = cert222->getName();
+
+  // Add a certificate
+  // This will also add the corresponding key and identity.
+  // Since there is no default setting before,
+  // The certificate will be set as the default one of the key, and so be the key and identity
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
+  db.addCertificate(*cert111);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+  BOOST_CHECK_EQUAL(db.getDefaultIdentity(), id1);
+  BOOST_CHECK_EQUAL(db.getDefaultKeyNameOfIdentity(id1), keyName11);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName111) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Add the second certificate of the same key
+  // Since default certificate already exists, no default setting changes.
+  BOOST_CHECK(db.getCertificate(certName112) == nullptr);
+  db.addCertificate(*cert112);
+  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName111);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 1);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName112) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Explicitly set the second certificate as the default one of the key.
+  db.setDefaultCertNameOfKey(certName112);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
+
+  // Delete the default certificate
+  // This will trigger certificateDeleted signal
+  // and also causes no default certificate for the key.
+  db.deleteCertificate(certName112);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 1);
+  BOOST_CHECK_EQUAL(deletedCerts[0], certName112);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), PibDb::NON_EXISTING_CERTIFICATE);
+  deletedCerts.clear();
+
+  // Add the second certificate back
+  // Since there is no default certificate of the key (though another certificate still exists),
+  // the new added certificate will be set as default
+  db.addCertificate(*cert112);
+  BOOST_CHECK(db.getCertificate(certName112) != nullptr);
+  BOOST_CHECK_EQUAL(db.getDefaultCertNameOfKey(keyName11), certName112);
+  insertedCerts.clear();
+
+  // Add entries for delete tests
+  db.addCertificate(*cert111); // already exists no certInserted signal emitted
+  db.addCertificate(*cert112); // already exists no certInserted signal emitted
+  db.addCertificate(*cert121);
+  db.addCertificate(*cert122);
+  db.addCertificate(*cert211);
+  db.addCertificate(*cert212);
+  db.addCertificate(*cert221);
+  db.addCertificate(*cert222);
+  BOOST_CHECK_EQUAL(insertedCerts.size(), 6);
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName121) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName122) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName211) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName212) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName221) !=
+              insertedCerts.end());
+  BOOST_CHECK(std::find(insertedCerts.begin(), insertedCerts.end(), certName222) !=
+              insertedCerts.end());
+  insertedCerts.clear();
+
+  // Delete the key.
+  // All the related certificates will be deleted as well.
+  db.deleteKey(keyName11);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 2);
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 1);
+  BOOST_CHECK_EQUAL(deletedKeys[0], keyName11);
+  deletedCerts.clear();
+  deletedKeys.clear();
+
+  // Recover deleted entries
+  db.addCertificate(*cert111);
+  db.addCertificate(*cert112);
+
+  // Delete the identity
+  // All the related certificates and keys will be deleted as well.
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), true);
+  db.deleteIdentity(id1);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName112), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName111), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName122), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName121), false);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName212), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName211), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName222), true);
+  BOOST_CHECK_EQUAL(db.hasCertificate(certName221), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName11), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName12), false);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName21), true);
+  BOOST_CHECK_EQUAL(db.hasKey(keyName22), true);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id1), false);
+  BOOST_CHECK_EQUAL(db.hasIdentity(id2), true);
+  BOOST_CHECK_EQUAL(deletedCerts.size(), 4);
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName111) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName112) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName121) !=
+              deletedCerts.end());
+  BOOST_CHECK(std::find(deletedCerts.begin(), deletedCerts.end(), certName122) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedKeys.size(), 2);
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName11) !=
+              deletedKeys.end());
+  BOOST_CHECK(std::find(deletedKeys.begin(), deletedKeys.end(), keyName12) !=
+              deletedCerts.end());
+  BOOST_CHECK_EQUAL(deletedIds.size(), 1);
+  BOOST_CHECK_EQUAL(deletedIds[0], id1);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace tests
+} // namespace pib
+} // namespace ndn
