build: Making build system consistent with other NDN projects and adding unit-test framework

This commit aims only at correcting building system and adding unit-test framework.
Existing test cases (ChronoSync) are disabled temporarily and will be fixed later.
Minimum changes are made, so that the code can be built successfully.
Compiling warnings will be resolved in a later commit.

Refs: #1495

Change-Id: Ibf7119bbd77b6307cb58bbee47b61d7a7312df98
diff --git a/tests/boost-test.hpp b/tests/boost-test.hpp
new file mode 100644
index 0000000..398be51
--- /dev/null
+++ b/tests/boost-test.hpp
@@ -0,0 +1,34 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  University of Memphis
+ *                     Regents of the University of California,
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR 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.
+ *
+ * NLSR 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
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+
+#ifndef NDN_TESTS_BOOST_TEST_HPP
+#define NDN_TESTS_BOOST_TEST_HPP
+
+// suppress warnings from Boost.Test
+#pragma GCC system_header
+#pragma clang system_header
+
+#include <boost/test/unit_test.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/test/output_test_stream.hpp>
+
+#endif // NDN_TESTS_BOOST_TEST_HPP
diff --git a/tests/main.cpp b/tests/main.cpp
new file mode 100644
index 0000000..9930f26
--- /dev/null
+++ b/tests/main.cpp
@@ -0,0 +1,24 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2014  University of Memphis,
+ *                     Regents of the University of California
+ *
+ * This file is part of NLSR (Named-data Link State Routing).
+ * See AUTHORS.md for complete list of NLSR authors and contributors.
+ *
+ * NLSR 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.
+ *
+ * NLSR 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
+ * NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+#define BOOST_TEST_MAIN 1
+#define BOOST_TEST_DYN_LINK 1
+
+#include "boost-test.hpp"
diff --git a/tests/nsync/test-digest.cc.tmp b/tests/nsync/test-digest.cc.tmp
new file mode 100644
index 0000000..4815919
--- /dev/null
+++ b/tests/nsync/test-digest.cc.tmp
@@ -0,0 +1,104 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Chaoyi Bian <bcy@pku.edu.cn>
+ *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/output_test_stream.hpp> 
+using boost::test_tools::output_test_stream;
+
+#include "sync-digest.h"
+#include <iostream>
+#include <sstream>
+
+using namespace Sync;
+using namespace Sync::Error;
+using namespace std;
+using namespace boost;
+
+BOOST_AUTO_TEST_SUITE(DigestTests)
+
+BOOST_AUTO_TEST_CASE (BasicTest)
+{
+  Digest d0;
+  BOOST_REQUIRE (d0.empty ());
+}
+
+BOOST_AUTO_TEST_CASE (DigestGenerationTest)
+{
+  Digest d1;
+  BOOST_CHECK_NO_THROW (d1 << "1\n");
+
+  // without explicit finalizing, Digest will not be complete and printing out will cause assert
+  BOOST_CHECK (d1.empty ());
+
+  // fix hash
+  d1.finalize ();
+  
+  BOOST_CHECK_NO_THROW (d1.getHash ());
+  BOOST_CHECK (!d1.empty ());
+  BOOST_CHECK (d1 == d1);
+
+  BOOST_CHECK_THROW (d1 << "2", DigestCalculationError);
+  
+  output_test_stream output;
+  BOOST_CHECK_NO_THROW (output << d1);
+  // BOOST_CHECK (output.check_length (40, false) );
+  // BOOST_CHECK (output.is_equal ("e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e", true)); // for sha1
+	BOOST_CHECK (output.check_length (64, false) );
+	BOOST_CHECK (output.is_equal ("4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865", true)); // for sha256
+}
+
+BOOST_AUTO_TEST_CASE (DigestComparison)
+{
+  Digest d1;
+  BOOST_CHECK_NO_THROW (d1 << "1\n");
+  // BOOST_CHECK_THROW (d1 == d1, DigestCalculationError);
+  BOOST_CHECK_NO_THROW (d1.finalize ());
+  BOOST_CHECK (d1 == d1);
+  
+  Digest d2;
+  BOOST_CHECK_NO_THROW (d2 << "2\n");
+  BOOST_CHECK_NO_THROW (d2.finalize ());
+  BOOST_CHECK (d1 != d2);
+  
+  Digest d3;
+  // istringstream is (string ("e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // real sha-1 for "1\n"
+	istringstream is (string ("4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865")); // real sha256 for "1\n"
+  BOOST_CHECK_NO_THROW (is >> d3);
+  BOOST_CHECK (!d3.empty ());
+  BOOST_CHECK (d3 == d1);
+  BOOST_CHECK (d3 != d2);
+
+  istringstream is2 (string ("25fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // some fake hash
+  BOOST_CHECK_THROW (is2 >> d3, DigestCalculationError); // >> can be used only once
+
+  Digest d4;
+  BOOST_CHECK_THROW (is2 >> d4, DigestCalculationError); // is2 is now empty. empty >> is not allowed
+
+  istringstream is3 (string ("25fa44f2b31c1fb553b6021e7360d07d5d91ff5e")); // some fake hash
+  BOOST_CHECK_NO_THROW (is3 >> d4);
+  
+  BOOST_CHECK (d4 != d1);
+  BOOST_CHECK (d4 != d2);
+  BOOST_CHECK (d4 != d3);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/nsync/test-leaf.cc.tmp b/tests/nsync/test-leaf.cc.tmp
new file mode 100644
index 0000000..49afcc5
--- /dev/null
+++ b/tests/nsync/test-leaf.cc.tmp
@@ -0,0 +1,108 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Chaoyi Bian <bcy@pku.edu.cn>
+ *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/output_test_stream.hpp> 
+using boost::test_tools::output_test_stream;
+
+#include <boost/make_shared.hpp>
+
+#include "sync-full-leaf.h"
+#include "sync-diff-leaf.h"
+#include "sync-std-name-info.h"
+
+using namespace Sync;
+using namespace std;
+using namespace boost;
+
+BOOST_AUTO_TEST_SUITE(LeafTests)
+
+BOOST_AUTO_TEST_CASE (LeafBase)
+{
+  NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
+  BOOST_CHECK (name != 0);
+
+  // find the same name
+  BOOST_CHECK (name.get () == StdNameInfo::FindOrCreate ("/test/name").get ());
+  BOOST_CHECK_EQUAL (name.use_count (), 1);
+
+  BOOST_CHECK_NO_THROW (DiffLeaf x (name, SeqNo (12)));
+  BOOST_CHECK_EQUAL (name.use_count (), 1);
+  
+  BOOST_CHECK_NO_THROW (DiffLeaf x (name));
+  BOOST_CHECK_EQUAL (name.use_count (), 1);
+
+  DiffLeaf updateLeaf (name, SeqNo (12));
+  BOOST_CHECK_EQUAL (name.use_count (), 2);
+
+  DiffLeaf removeLeaf (name);
+  BOOST_CHECK_EQUAL (name.use_count (), 3);
+
+  BOOST_CHECK_EQUAL (updateLeaf.getOperation (), UPDATE);
+  BOOST_CHECK_EQUAL (updateLeaf.getSeq ().getSession (), 0);
+  BOOST_CHECK_EQUAL (updateLeaf.getSeq ().getSeq (), 12);
+  
+  BOOST_CHECK_EQUAL (removeLeaf.getOperation (), REMOVE);
+  BOOST_CHECK_EQUAL (removeLeaf.getSeq ().getSession (), 0);
+  BOOST_CHECK_EQUAL (removeLeaf.getSeq ().getSeq (), 0);
+  
+  BOOST_REQUIRE_NO_THROW (FullLeaf x (name, SeqNo (12)));
+  FullLeaf fullLeaf (name, SeqNo (12));
+  BOOST_CHECK_EQUAL (name.use_count (), 4);
+}
+
+BOOST_AUTO_TEST_CASE (LeafDigest)
+{
+  BOOST_CHECK_EQUAL (StdNameInfo::FindOrCreate ("/test/name").use_count (), 1);
+  NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
+  FullLeaf fullLeaf (name, SeqNo (12));
+
+  // fullLeafDigest = hash ( hash(name), hash (session, seqNo) )
+  
+  // Digest manualDigest;
+
+  // Digest manualNameDigest;
+  // manualNameDigest << "/test/name";
+  // manualNameDigest.finalize ();
+
+  // Digest manualSeqNoDigest;
+  // manualSeqNoDigest << 0 << 13;
+  // manualSeqNoDigest.finalize ();
+
+  // manualDigest << manualNameDigest << manualSeqNoDigest;
+  // manualDigest.finalize ();
+
+  // cout << manualDigest << "\n\n";
+
+  output_test_stream output;
+  output << fullLeaf.getDigest ();
+  // BOOST_CHECK (output.is_equal ("991f8cf6262dfe0f519c63f6e9b92fe69e741a9b", true)); // for sha1
+	BOOST_CHECK (output.is_equal ("526d63e6e1f05f97502fd500a1729c4907f3841483ae4561b7e6307c40188f35", true)); // for sha256
+
+  fullLeaf.setSeq (SeqNo (13));
+  output << fullLeaf.getDigest ();
+  BOOST_CHECK (!output.is_equal ("991f8cf6262dfe0f519c63f6e9b92fe69e741a9b", false));
+  // BOOST_CHECK (output.is_equal ("585a8687ab41d5c29f86e5906c8f188ddca816b3", true)); // for sha1
+	BOOST_CHECK (output.is_equal ("39fefe65b3e1021776c07d3a9a3023c6c7cdf12724ee7f3a98b813b22f46d5ec", true)); // for sha256
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/nsync/test-state.cc.outdated b/tests/nsync/test-state.cc.outdated
new file mode 100644
index 0000000..35fc79c
--- /dev/null
+++ b/tests/nsync/test-state.cc.outdated
@@ -0,0 +1,294 @@
+/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil -*- */
+/*
+ * Copyright (c) 2012 University of California, Los Angeles
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Author: Zhenkai Zhu <zhenkai@cs.ucla.edu>
+ *         Chaoyi Bian <bcy@pku.edu.cn>
+ *	   Alexander Afanasyev <alexander.afanasyev@ucla.edu>
+ */
+
+#define BOOST_TEST_DYN_LINK 1
+#define BOOST_TEST_NO_MAIN 1
+// #define BOOST_TEST_MODULE StateTests
+#include <boost/test/unit_test.hpp>
+#include <boost/test/output_test_stream.hpp> 
+using boost::test_tools::output_test_stream;
+
+#include <boost/make_shared.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+
+#include "sync-std-name-info.h"
+#include "sync-full-state.h"
+#include "sync-diff-state.h"
+
+using namespace Sync;
+using namespace std;
+using namespace boost;
+
+BOOST_AUTO_TEST_SUITE(StateTests)
+
+BOOST_AUTO_TEST_CASE (FullStateTest)
+{
+  BOOST_CHECK_NO_THROW (FullState ());
+  FullState state;
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
+
+  output_test_stream output;
+  output << state.getTimeFromLastUpdate ();
+  BOOST_CHECK (output.is_equal ("not-a-date-time", true));
+
+  NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
+  BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
+
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
+  BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
+
+  BOOST_CHECK_NO_THROW (state.remove (name));
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
+
+  BOOST_CHECK_EQUAL (state.getTimeFromLastUpdate ().total_milliseconds (), 0);
+}
+
+BOOST_AUTO_TEST_CASE (DiffStateTest)
+{
+  BOOST_CHECK_NO_THROW (DiffState ());
+  DiffState state;
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
+
+  NameInfoConstPtr name = StdNameInfo::FindOrCreate ("/test/name");
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (12)));
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
+  BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 12);
+
+  BOOST_CHECK_NO_THROW (state.update (name, SeqNo (13)));
+  BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 13);
+
+  BOOST_CHECK_NO_THROW (state.remove (name));
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 1);
+  BOOST_CHECK_EQUAL ((*state.getLeaves ().begin ())->getSeq ().getSeq (), 0);
+}
+
+BOOST_AUTO_TEST_CASE (FullStateDigestTest)
+{
+  FullState state;
+  BOOST_CHECK_EQUAL (state.getLeaves ().size (), 0);
+
+  NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
+  NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
+  NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
+
+  state.update (name1, SeqNo (10));
+  DigestConstPtr digest1 = state.getDigest ();
+
+  state.update (name2, SeqNo (12));
+  DigestConstPtr digest2 = state.getDigest ();
+
+  BOOST_CHECK (digest1.get () != digest2.get ());
+  BOOST_CHECK (!digest1->empty ());
+  BOOST_CHECK (!digest2->empty ());
+
+  state.update (name3, SeqNo (8));
+  DigestConstPtr digest3 = state.getDigest ();
+
+  BOOST_CHECK (digest1.get () != digest2.get ());
+  BOOST_CHECK (digest2.get () != digest3.get ());
+  BOOST_CHECK (digest1.get () != digest3.get ());
+
+  BOOST_CHECK (*digest1 != *digest2);
+  BOOST_CHECK (*digest2 != *digest3);
+  BOOST_CHECK (*digest1 != *digest3);
+
+  // removing elements. Digest should get reverted to digest1
+  state.remove (name2);
+  state.remove (name3);
+  DigestConstPtr digest4 = state.getDigest ();
+  BOOST_CHECK (*digest1 == *digest4);
+
+  name2.reset (); // force destructor
+  name3.reset (); // force destructor
+  name3 = StdNameInfo::FindOrCreate ("3"); // this will enforce different (larger) hashing ID of name
+  name2 = StdNameInfo::FindOrCreate ("2"); // this will enforce different (larger) hashing ID of name
+  
+  // adding in different order
+  state.update (name3, SeqNo (8));
+  state.update (name2, SeqNo (12));
+  DigestConstPtr digest5 = state.getDigest ();
+  BOOST_CHECK (*digest5 == *digest3);
+}
+
+BOOST_AUTO_TEST_CASE (FullStateXml)
+{
+  FullState state;
+
+  NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
+  NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
+  NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
+
+  state.update (name1, SeqNo (10));
+  state.update (name2, SeqNo (12));
+  state.update (name3, SeqNo (8));  
+
+  string xml1 = "<state>"
+    "<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
+    "<item><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
+    "<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
+    "</state>";
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  // cout << s << endl; 
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, xml1);
+  }
+  
+  state.remove (name2);
+  string xml2 = "<state>"
+    "<item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
+    "<item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
+    "</state>";
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, xml2);
+  }
+
+  FullState state2;
+  istringstream xml1_is (xml1);
+  BOOST_CHECK_NO_THROW (xml1_is >> state2);
+  {
+  ostringstream os;
+  os << state2;
+  string xml1_test = os.str ();
+  erase_all (xml1_test, "\n");
+  BOOST_CHECK_EQUAL (xml1_test, xml1);
+  }
+  
+  istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
+  BOOST_CHECK_NO_THROW (xml2_is >> state2);
+  
+  {
+  ostringstream os;
+  os << state2;
+  string xml2_test = os.str ();
+  erase_all (xml2_test, "\n");
+  BOOST_CHECK_EQUAL (xml2_test, xml2);
+  }
+}
+
+BOOST_AUTO_TEST_CASE (DiffStateXml)
+{
+  DiffState state;
+
+  NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
+  NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
+  NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
+
+  state.update (name1, SeqNo (10));
+  state.update (name2, SeqNo (12));
+  state.update (name3, SeqNo (8));  
+
+  string xml1 = "<state>"
+    "<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
+    "<item action=\"update\"><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item>"
+    "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
+    "</state>";
+  {
+  ostringstream os;
+  os << state;
+  string xml1_test = os.str ();
+  erase_all (xml1_test, "\n");
+  BOOST_CHECK_EQUAL (xml1_test, xml1);
+  }
+  
+  state.remove (name2);
+  string xml2 = "<state>"
+    "<item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item>"
+    "<item action=\"remove\"><name>2</name></item>"
+    "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item>"
+    "</state>";
+  {
+  ostringstream os;
+  os << state;
+  string xml2_test = os.str ();
+  erase_all (xml2_test, "\n");
+  BOOST_CHECK_EQUAL (xml2_test, xml2);
+  }
+
+  ////////////  ////////////  ////////////  ////////////  ////////////  ////////////
+  
+  DiffState state2;
+  istringstream xml1_is (xml1);
+  BOOST_CHECK_NO_THROW (xml1_is >> state2);
+  
+  {
+  ostringstream os;
+  os << state2;
+  string xml1_test = os.str ();
+  erase_all (xml1_test, "\n");
+  BOOST_CHECK_EQUAL (xml1_test, xml1);
+  }
+
+  istringstream xml2_is ("<state><item action=\"remove\"><name>2</name></item></state>");
+  BOOST_CHECK_NO_THROW (xml2_is >> state2);
+  
+  {
+  ostringstream os;
+  os << state2;
+  string xml2_test = os.str ();
+  erase_all (xml2_test, "\n");
+  BOOST_CHECK_EQUAL (xml2_test, xml2);
+  }
+
+}
+
+BOOST_AUTO_TEST_CASE (DiffStateDiffTest)
+{
+  DiffStatePtr root = make_shared<DiffState> ();
+
+  DiffStatePtr head = make_shared<DiffState> ();
+  root->setNext (head);
+  
+  head->update (StdNameInfo::FindOrCreate ("3"), SeqNo (1));
+  head->remove (StdNameInfo::FindOrCreate ("1"));
+  
+  DiffStatePtr tail = make_shared<DiffState> ();
+  head->setNext (tail);
+
+  tail->update (StdNameInfo::FindOrCreate ("3"), SeqNo (2));  
+
+  {
+  ostringstream os;
+  os << *root->diff ();
+  string diffState = os.str ();
+  erase_all (diffState, "\n");
+  BOOST_CHECK_EQUAL (diffState,
+                     "<state>"
+                     "<item action=\"remove\"><name>1</name></item>"
+                     "<item action=\"update\"><name>3</name><seq><session>0</session><seqno>2</seqno></seq></item>"
+                     "</state>");
+  }
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/tests/wscript b/tests/wscript
new file mode 100644
index 0000000..3ac955e
--- /dev/null
+++ b/tests/wscript
@@ -0,0 +1,53 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+"""
+Copyright (c) 2014  University of Memphis
+                    Regents of the University of California,
+
+This file is part of NLSR (Named-data Link State Routing).
+See AUTHORS.md for complete list of NLSR authors and contributors.
+
+NLSR 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.
+
+NLSR 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
+NLSR, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+top = '..'
+
+def build(bld):
+    # Unit tests
+    if bld.env['WITH_TESTS']:
+        unit_test_main = bld(
+            target='unit-tests-main',
+            name='unit-tests-main',
+            features='cxx',
+            source=bld.path.ant_glob(['*.cpp']),
+            use='nlsr-objects',
+          )
+
+        # nsync tests
+        unit_tests_nsync = bld.program(
+            target='../unit-tests-nsync',
+            features='cxx cxxprogram',
+            source=bld.path.ant_glob(['nsync/**/*.cc']),
+            use='nsync-objects unit-tests-main',
+            includes='.',
+            install_prefix=None,
+          )
+
+        # nlsr tests
+        unit_tests_nlsr = bld.program(
+            target='../unit-tests-nlsr',
+            features='cxx cxxprogram',
+            source=bld.path.ant_glob(['nlsr/**/*.cpp']),
+            use='nslr-objects unit-tests-main',
+            includes='.',
+            install_prefix=None,
+          )