diff --git a/tests/unit-tests/group-manager.t.cpp b/tests/unit-tests/group-manager.t.cpp
new file mode 100644
index 0000000..1d25698
--- /dev/null
+++ b/tests/unit-tests/group-manager.t.cpp
@@ -0,0 +1,354 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014-2015,  Regents of the University of California
+ *
+ * This file is part of ndn-group-encrypt (Group-based Encryption Protocol for NDN).
+ * See AUTHORS.md for complete list of ndn-group-encrypt authors and contributors.
+ *
+ * ndn-group-encrypt 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.
+ *
+ * ndn-group-encrypt 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
+ * ndn-group-encrypt, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * @author Zhiyi Zhang <dreamerbarrychang@gmail.com>
+ */
+
+#include "group-manager.hpp"
+#include "boost-test.hpp"
+#include "algo/rsa.hpp"
+#include "algo/aes.hpp"
+#include "encrypted-content.hpp"
+
+#include <boost/filesystem.hpp>
+#include <ndn-cxx/encoding/buffer-stream.hpp>
+#include <string>
+
+namespace ndn {
+namespace gep {
+namespace tests {
+
+using namespace boost::posix_time;
+
+const uint8_t SIG_INFO[] = {
+  0x16, 0x1b, // SignatureInfo
+      0x1b, 0x01, // SignatureType
+          0x01,
+      0x1c, 0x16, // KeyLocator
+          0x07, 0x14, // Name
+              0x08, 0x04,
+                  0x74, 0x65, 0x73, 0x74,
+              0x08, 0x03,
+                  0x6b, 0x65, 0x79,
+              0x08, 0x07,
+                  0x6c, 0x6f, 0x63, 0x61, 0x74, 0x6f, 0x72
+};
+
+const uint8_t SIG_VALUE[] = {
+  0x17, 0x80, // SignatureValue
+      0x2f, 0xd6, 0xf1, 0x6e, 0x80, 0x6f, 0x10, 0xbe, 0xb1, 0x6f, 0x3e, 0x31, 0xec,
+      0xe3, 0xb9, 0xea, 0x83, 0x30, 0x40, 0x03, 0xfc, 0xa0, 0x13, 0xd9, 0xb3, 0xc6,
+      0x25, 0x16, 0x2d, 0xa6, 0x58, 0x41, 0x69, 0x62, 0x56, 0xd8, 0xb3, 0x6a, 0x38,
+      0x76, 0x56, 0xea, 0x61, 0xb2, 0x32, 0x70, 0x1c, 0xb6, 0x4d, 0x10, 0x1d, 0xdc,
+      0x92, 0x8e, 0x52, 0xa5, 0x8a, 0x1d, 0xd9, 0x96, 0x5e, 0xc0, 0x62, 0x0b, 0xcf,
+      0x3a, 0x9d, 0x7f, 0xca, 0xbe, 0xa1, 0x41, 0x71, 0x85, 0x7a, 0x8b, 0x5d, 0xa9,
+      0x64, 0xd6, 0x66, 0xb4, 0xe9, 0x8d, 0x0c, 0x28, 0x43, 0xee, 0xa6, 0x64, 0xe8,
+      0x55, 0xf6, 0x1c, 0x19, 0x0b, 0xef, 0x99, 0x25, 0x1e, 0xdc, 0x78, 0xb3, 0xa7,
+      0xaa, 0x0d, 0x14, 0x58, 0x30, 0xe5, 0x37, 0x6a, 0x6d, 0xdb, 0x56, 0xac, 0xa3,
+      0xfc, 0x90, 0x7a, 0xb8, 0x66, 0x9c, 0x0e, 0xf6, 0xb7, 0x64, 0xd1
+};
+
+class GroupManagerFixture
+{
+public:
+  GroupManagerFixture()
+    : tmpPath(boost::filesystem::path(TMP_TESTS_PATH))
+  {
+    boost::filesystem::create_directories(tmpPath);
+
+    // generate the certificate public key
+    RandomNumberGenerator rng;
+    RsaKeyParams params;
+    DecryptKey<algo::Rsa> memberDecryptKey = algo::Rsa::generateKey(rng, params);
+    decryptKeyBuf = memberDecryptKey.getKeyBits();
+    EncryptKey<algo::Rsa> memberEncryptKey = algo::Rsa::deriveEncryptKey(decryptKeyBuf);
+    encryptKeyBuf = memberEncryptKey.getKeyBits();
+
+    // generate certificate
+    cert.setName(Name("/ndn/memberA/KEY/ksk-123/ID-CERT/123"));
+    PublicKey contentPubKey(encryptKeyBuf.buf(), encryptKeyBuf.size());
+    cert.setPublicKeyInfo(contentPubKey);
+    cert.encode();
+
+    Block sigInfoBlock(SIG_INFO, sizeof(SIG_INFO));
+    Block sigValueBlock(SIG_VALUE, sizeof(SIG_VALUE));
+
+    Signature sig(sigInfoBlock, sigValueBlock);
+    cert.setSignature(sig);
+
+    auto dataBlock = cert.wireEncode();
+  }
+
+  void
+  setManager(GroupManager& manager)
+  {
+    // set the first schedule
+    Schedule schedule1;
+    RepetitiveInterval interval11(from_iso_string("20150825T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  5, 10, 2, RepetitiveInterval::RepeatUnit::DAY);
+    RepetitiveInterval interval12(from_iso_string("20150825T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  6, 8, 1, RepetitiveInterval::RepeatUnit::DAY);
+    RepetitiveInterval interval13(from_iso_string("20150827T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  7, 8);
+    schedule1.addWhiteInterval(interval11);
+    schedule1.addWhiteInterval(interval12);
+    schedule1.addBlackInterval(interval13);
+
+    // set the second schedule
+    Schedule schedule2;
+    RepetitiveInterval interval21(from_iso_string("20150825T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  9, 12, 1, RepetitiveInterval::RepeatUnit::DAY);
+    RepetitiveInterval interval22(from_iso_string("20150827T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  6, 8);
+    RepetitiveInterval interval23(from_iso_string("20150827T000000"),
+                                  from_iso_string("20150827T000000"),
+                                  2, 4);
+    schedule2.addWhiteInterval(interval21);
+    schedule2.addWhiteInterval(interval22);
+    schedule2.addBlackInterval(interval23);
+
+    // add to the group manager db
+    manager.addSchedule("schedule1", schedule1);
+    manager.addSchedule("schedule2", schedule2);
+
+    // do some adaptions to certificate
+    Block dataBlock = cert.wireEncode();
+
+    Data memberA(dataBlock);
+    memberA.setName(Name("/ndn/memberA/KEY/ksk-123/ID-CERT/123"));
+    Data memberB(dataBlock);
+    memberB.setName(Name("/ndn/memberB/KEY/ksk-123/ID-CERT/123"));
+    Data memberC(dataBlock);
+    memberC.setName(Name("/ndn/memberC/KEY/ksk-123/ID-CERT/123"));
+
+    // add members to the database
+    manager.addMember("schedule1", memberA);
+    manager.addMember("schedule1", memberB);
+    manager.addMember("schedule2", memberC);
+  }
+
+  ~GroupManagerFixture()
+  {
+    boost::filesystem::remove_all(tmpPath);
+  }
+
+public:
+  boost::filesystem::path tmpPath;
+  Buffer decryptKeyBuf;
+  Buffer encryptKeyBuf;
+  IdentityCertificate cert;
+};
+
+BOOST_FIXTURE_TEST_SUITE(TestGroupManager, GroupManagerFixture)
+
+BOOST_AUTO_TEST_CASE(CreateDKeyData)
+{
+  // create the group manager database
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/manager-d-key-test.db";
+  GroupManager manager(Name("Alice-read"), dbDir, 2048, 1);
+
+  Block newCertBlock = cert.wireEncode();
+  IdentityCertificate newCert(newCertBlock);
+
+  // encrypt D-KEY
+  Data data = manager.createDKeyData("20150825T000000", "20150827T000000", Name("/ndn/memberA/KEY"),
+                                     decryptKeyBuf, newCert.getPublicKeyInfo().get());
+
+  // verify encrypted D-KEY
+  Block dataContent = data.getContent();
+  dataContent.parse();
+  BOOST_CHECK_EQUAL(dataContent.elements_size(), 2);
+
+  // get nonce key
+  Block::element_const_iterator contentIterator = dataContent.elements_begin();
+  Block nonceContent(*contentIterator);
+  BOOST_CHECK_EQUAL(nonceContent.type(), tlv::EncryptedContent);
+  EncryptedContent encryptedNonce(nonceContent);
+  BOOST_CHECK_EQUAL(encryptedNonce.getInitialVector().size(), 0);
+  BOOST_CHECK_EQUAL(encryptedNonce.getAlgorithmType(), tlv::AlgorithmRsaPkcs);
+
+  const Buffer& bufferNonce = encryptedNonce.getPayload();
+  algo::EncryptParams decryptParams(tlv::AlgorithmRsaPkcs);
+  Buffer nonce = algo::Rsa::decrypt(decryptKeyBuf.buf(), decryptKeyBuf.size(),
+                                    bufferNonce.buf(), bufferNonce.size(), decryptParams);
+
+  // get D-KEY
+  contentIterator++;
+  Block payloadContent(*contentIterator);
+  BOOST_CHECK_EQUAL(payloadContent.type(), tlv::EncryptedContent);
+  EncryptedContent encryptedPayload(payloadContent);
+  BOOST_CHECK_EQUAL(encryptedPayload.getInitialVector().size(), 16);
+  BOOST_CHECK_EQUAL(encryptedPayload.getAlgorithmType(), tlv::AlgorithmAesCbc);
+
+  decryptParams.setAlgorithmType(tlv::AlgorithmAesCbc);
+  decryptParams.setIV(encryptedPayload.getInitialVector().buf(),
+                      encryptedPayload.getInitialVector().size());
+  const Buffer& bufferPayload = encryptedPayload.getPayload();
+  Buffer largePayload = algo::Aes::decrypt(nonce.buf(), nonce.size(),
+                                           bufferPayload.buf(), bufferPayload.size(),
+                                           decryptParams);
+
+  BOOST_CHECK_EQUAL_COLLECTIONS(largePayload.begin(), largePayload.end(),
+                                decryptKeyBuf.begin(), decryptKeyBuf.end());
+}
+
+BOOST_AUTO_TEST_CASE(CreateEKeyData)
+{
+  // create the group manager database
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/manager-e-key-test.db";
+
+  // create group manager
+  GroupManager manager(Name("Alice-read"), dbDir, 1024, 1);
+  setManager(manager);
+
+  Data data = manager.createEKeyData("20150825T090000", "20150825T110000", encryptKeyBuf);
+  BOOST_CHECK_EQUAL(data.getName().toUri(), "/Alice-read/E-KEY/20150825T090000/20150825T110000");
+
+  Buffer contentBuf(data.getContent().value(), data.getContent().value_size());
+  BOOST_CHECK_EQUAL_COLLECTIONS(encryptKeyBuf.begin(), encryptKeyBuf.end(),
+                                contentBuf.begin(), contentBuf.end());
+
+}
+
+BOOST_AUTO_TEST_CASE(CalculateInterval)
+{
+  // create the group manager database
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/manager-interval-test.db";
+
+  // create group manager
+  GroupManager manager(Name("Alice-read"), dbDir, 1024, 1);
+  setManager(manager);
+
+  std::map<Name, Buffer> memberKeys;
+  Interval result;
+
+  TimeStamp tp1(from_iso_string("20150825T093000"));
+  result = manager.calculateInterval(tp1, memberKeys);
+  BOOST_CHECK_EQUAL(to_iso_string(result.getStartTime()), "20150825T090000");
+  BOOST_CHECK_EQUAL(to_iso_string(result.getEndTime()), "20150825T100000");
+
+  TimeStamp tp2(from_iso_string("20150827T073000"));
+  result = manager.calculateInterval(tp2, memberKeys);
+  BOOST_CHECK_EQUAL(to_iso_string(result.getStartTime()), "20150827T070000");
+  BOOST_CHECK_EQUAL(to_iso_string(result.getEndTime()), "20150827T080000");
+
+  TimeStamp tp3(from_iso_string("20150827T043000"));
+  result = manager.calculateInterval(tp3, memberKeys);
+  BOOST_CHECK_EQUAL(result.isValid(), false);
+
+  TimeStamp tp4(from_iso_string("20150827T053000"));
+  result = manager.calculateInterval(tp4, memberKeys);
+  BOOST_CHECK_EQUAL(to_iso_string(result.getStartTime()), "20150827T050000");
+  BOOST_CHECK_EQUAL(to_iso_string(result.getEndTime()), "20150827T060000");
+}
+
+BOOST_AUTO_TEST_CASE(GetGroupKey)
+{
+  // create the group manager database
+  std::string dbDir = tmpPath.c_str();
+  dbDir += "/manager-group-key-test.db";
+
+  // create group manager
+  GroupManager manager(Name("Alice-read"), dbDir, 1024, 1);
+  setManager(manager);
+
+  // get data list from group manager
+  TimeStamp tp1(from_iso_string("20150825T093000"));
+  std::list<Data> result = manager.getGroupKey(tp1);
+
+  BOOST_CHECK_EQUAL(result.size(), 4);
+
+  // first data contain the group encrypt key(public key)
+  std::list<Data>::iterator dataIterator = result.begin();
+  BOOST_CHECK_EQUAL(dataIterator->getName().toUri(),
+                    "/Alice-read/E-KEY/20150825T090000/20150825T100000");
+  EncryptKey<algo::Rsa> groupEKey(Buffer(dataIterator->getContent().value(),
+                                         dataIterator->getContent().value_size()));
+
+  // second data and decrypt
+  dataIterator++;
+  BOOST_CHECK_EQUAL(dataIterator->getName().getPrefix(-2).toUri(),
+                    "/Alice-read/D-KEY/20150825T090000/20150825T100000");
+
+  //////////////////////////////////////////////////////////////////////// start decryption
+  Block dataContent = dataIterator->getContent();
+
+  dataContent.parse();
+  BOOST_CHECK_EQUAL(dataContent.elements_size(), 2);
+
+  // get nonce key
+  Block::element_const_iterator contentIterator = dataContent.elements_begin();
+  Block nonceContent(*contentIterator);
+  BOOST_CHECK_EQUAL(nonceContent.type(), tlv::EncryptedContent);
+  EncryptedContent encryptedNonce(nonceContent);
+  BOOST_CHECK_EQUAL(encryptedNonce.getInitialVector().size(), 0);
+  BOOST_CHECK_EQUAL(encryptedNonce.getAlgorithmType(), tlv::AlgorithmRsaPkcs);
+
+  algo::EncryptParams decryptParams(tlv::AlgorithmRsaPkcs);
+  const Buffer& bufferNonce = encryptedNonce.getPayload();
+  Buffer nonce = algo::Rsa::decrypt(decryptKeyBuf.buf(), decryptKeyBuf.size(),
+                                    bufferNonce.buf(), bufferNonce.size(), decryptParams);
+
+  // get buffer payload
+  contentIterator++;
+  Block payloadContent(*contentIterator);
+  BOOST_CHECK_EQUAL(payloadContent.type(), tlv::EncryptedContent);
+  EncryptedContent encryptedPayload(payloadContent);
+  BOOST_CHECK_EQUAL(encryptedPayload.getInitialVector().size(), 16);
+  BOOST_CHECK_EQUAL(encryptedPayload.getAlgorithmType(), tlv::AlgorithmAesCbc);
+
+  decryptParams.setAlgorithmType(tlv::AlgorithmAesCbc);
+  decryptParams.setIV(encryptedPayload.getInitialVector().buf(),
+                      encryptedPayload.getInitialVector().size());
+  const Buffer& bufferPayload = encryptedPayload.getPayload();
+  Buffer largePayload = algo::Aes::decrypt(nonce.buf(), nonce.size(),
+                                           bufferPayload.buf(), bufferPayload.size(),
+                                           decryptParams);
+
+  // get group D-KEY
+  DecryptKey<algo::Rsa> groupDKey(Buffer(largePayload.buf(), largePayload.size()));
+
+  /////////////////////////////////////////////////////////////////////// end decryption
+
+  // check the D-KEY
+  EncryptKey<algo::Rsa> derivedGroupEKey = algo::Rsa::deriveEncryptKey(groupDKey.getKeyBits());
+  BOOST_CHECK_EQUAL_COLLECTIONS(groupEKey.getKeyBits().begin(), groupEKey.getKeyBits().end(),
+                                derivedGroupEKey.getKeyBits().begin(),
+                                derivedGroupEKey.getKeyBits().end());
+
+  // invalid time stamp to get group key
+  TimeStamp tp2(from_iso_string("20150826T083000"));
+  BOOST_CHECK_EQUAL(manager.getGroupKey(tp2).size(), 0);
+
+  TimeStamp tp3(from_iso_string("20150827T023000"));
+  BOOST_CHECK_EQUAL(manager.getGroupKey(tp3).size(), 0);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+} // namespace test
+} // namespace gep
+} // namespace ndn
