tests: Extending Face test cases

Add previously removed test cases to check if config-file based
transport customization works.

Change-Id: I7e2235494f2ba7011423e743ab8e437c74d56d1f
diff --git a/README-dev.md b/README-dev.md
index a96fce3..80ef497 100644
--- a/README-dev.md
+++ b/README-dev.md
@@ -42,3 +42,60 @@
 
 If you are affiliated to an NSF-supported NDN project institution, please use the [NDN Team License
 Boilerplate](http://redmine.named-data.net/projects/ndn-cxx/wiki/NDN_Team_License_Boilerplate_(ndn-cxx)).
+
+Running unit-tests
+------------------
+
+To run unit tests, ndn-cxx needs to be configured, build with unit test support, and installed
+into the configured location.  For example:
+
+    ./waf configure --with-tests
+    ./waf
+    sudo ./waf install
+
+**Note**: On Linux platform you also need to run `sudo ldconfig` to reconfigure dynamic loader
+run-time bindings.  On FreeBSD, use `sudo ldconfig -a` instead.
+
+The simplest way to run tests, is just to run the compiled binary without any parameters:
+
+    ./build/unit-tests
+
+[Boost.Test framework](http://www.boost.org/doc/libs/1_54_0/libs/test/doc/html/index.html)
+is very flexible and allows a number of run-time customization of what tests should be run.
+For example, it is possible to choose to run only a specific test suite, only a specific
+test case within a suite, or specific test cases within specific test suites:
+
+    # Run only Face test suite tests (tests/unit-tests/face.t.cpp)
+    ./build/unit-tests -t TestFace
+
+    # Run only test case ExpressInterestData from the same test suite
+    ./build/unit-tests -t TestFace/ExpressInterestData
+
+    # Run Basic test case from all test suites
+    ./build/unit-tests -t */Basic
+
+By default, Boost.Test framework will produce verbose output only when a test case fails.
+If it is desired to see verbose output (result of each test assertion), add `-l all`
+option to `./build/unit-tests` command.  To see test progress, you can use `-l test_suite`
+or `-p` to show progress bar:
+
+    # Show report all log messages including the passed test notification
+    ./build/unit-tests -l all
+
+    # Show test suite messages
+    ./build/unit-tests -l test_suite
+
+    # Show nothing
+    ./build/unit-tests -l nothing
+
+    # Show progress bar
+    ./build/unit-tests -p
+
+There are many more command line options available, information about which can be obtained
+either from the command line using `--help` switch, or online on
+[Boost.Test library](http://www.boost.org/doc/libs/1_54_0/libs/test/doc/html/index.html)
+website.
+
+**Warning:** If you have customized parameters for NDN platform using `client.conf` in
+`/etc/ndn` or `/usr/local/etc/ndn` (or other `@SYSCONFDIR@/etc` if it was configured to custom
+path during `./waf configure`), Face-related test cases may fail.
diff --git a/tests/key-chain-fixture.hpp b/tests/key-chain-fixture.hpp
index bf4e004..e9218a6 100644
--- a/tests/key-chain-fixture.hpp
+++ b/tests/key-chain-fixture.hpp
@@ -28,6 +28,8 @@
 #include "identity-management-fixture.hpp"
 
 #include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
+#include <fstream>
 
 namespace ndn {
 namespace tests {
@@ -84,6 +86,36 @@
   std::string m_oldTpm;
 };
 
+/**
+ * @brief Extension of PibDirFixture to set TEST_HOME variable and allow config file creation
+ */
+template<class Path>
+class TestHomeFixture : public PibDirFixture<Path>
+{
+public:
+  TestHomeFixture()
+  {
+    setenv("TEST_HOME", this->m_pibDir.c_str(), true);
+  }
+
+  ~TestHomeFixture()
+  {
+    unsetenv("TEST_HOME");
+  }
+
+  void
+  createClientConf(std::initializer_list<std::string> lines)
+  {
+    boost::filesystem::create_directories(boost::filesystem::path(this->m_pibDir) / ".ndn");
+    std::ofstream of((boost::filesystem::path(this->m_pibDir) / ".ndn" / "client.conf").c_str());
+    for (auto line : lines) {
+      boost::replace_all(line, "%PATH%", this->m_pibDir);
+      of << line << std::endl;
+    }
+  }
+};
+
+
 struct DefaultPibDir
 {
   const std::string PATH = "build/keys";
@@ -99,6 +131,7 @@
   KeyChainFixture();
 };
 
+
 } // namespace tests
 } // namespace ndn
 
diff --git a/tests/unit-tests/face.t.cpp b/tests/unit-tests/face.t.cpp
index ac87d37..877e6bd 100644
--- a/tests/unit-tests/face.t.cpp
+++ b/tests/unit-tests/face.t.cpp
@@ -620,24 +620,116 @@
   BOOST_CHECK(Face(transport, io, keyChain).getTransport() == transport);
 }
 
-BOOST_AUTO_TEST_CASE(CustomizeTransportWithEnv)
+BOOST_AUTO_TEST_SUITE(CustomizeTransport)
+
+class WithEnv : private IdentityManagementTimeFixture
+{
+public:
+  WithEnv()
+  {
+    if (getenv("NDN_CLIENT_TRANSPORT") != nullptr) {
+      m_oldTransport = getenv("NDN_CLIENT_TRANSPORT");
+      unsetenv("NDN_CLIENT_TRANSPORT");
+    }
+  }
+
+  void
+  configure(const std::string& faceUri)
+  {
+    setenv("NDN_CLIENT_TRANSPORT", faceUri.c_str(), true);
+  }
+
+  ~WithEnv()
+  {
+    if (!m_oldTransport.empty()) {
+      setenv("NDN_CLIENT_TRANSPORT", m_oldTransport.c_str(), true);
+    }
+    else {
+      unsetenv("NDN_CLIENT_TRANSPORT");
+    }
+  }
+
+private:
+  std::string m_oldTransport;
+};
+
+class WithConfig : private TestHomeFixture<DefaultPibDir>
+{
+public:
+  void
+  configure(const std::string& faceUri)
+  {
+    createClientConf({"transport=" + faceUri});
+  }
+};
+
+class WithEnvAndConfig : public WithEnv, public WithConfig
+{
+};
+
+typedef boost::mpl::vector<WithEnv, WithConfig> ConfigOptions;
+
+BOOST_FIXTURE_TEST_CASE(NoConfig, WithEnvAndConfig) // fixture configures test HOME and PIB/TPM path
 {
   shared_ptr<Face> face;
   BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
   BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
-
-  setenv("NDN_CLIENT_TRANSPORT", "tcp://localhost:6363", true);
-  BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
-  BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
-  unsetenv("NDN_CLIENT_TRANSPORT");
-
-  setenv("NDN_CLIENT_TRANSPORT", "wrong-transport:", true);
-  BOOST_CHECK_THROW(face = make_shared<Face>(), ConfigFile::Error);
-  unsetenv("NDN_CLIENT_TRANSPORT");
 }
 
-/// @todo Tests to create Face using the config file
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Unix, T, ConfigOptions, T)
+{
+  this->configure("unix://some/path");
 
+  shared_ptr<Face> face;
+  BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
+  BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(Tcp, T, ConfigOptions, T)
+{
+  this->configure("tcp://127.0.0.1:6000");
+
+  shared_ptr<Face> face;
+  BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
+  BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(WrongTransport, T, ConfigOptions, T)
+{
+  this->configure("wrong-transport:");
+
+  BOOST_CHECK_THROW(make_shared<Face>(), ConfigFile::Error);
+}
+
+BOOST_FIXTURE_TEST_CASE_TEMPLATE(WrongUri, T, ConfigOptions, T)
+{
+  this->configure("wrong-uri");
+
+  BOOST_CHECK_THROW(make_shared<Face>(), ConfigFile::Error);
+}
+
+BOOST_FIXTURE_TEST_CASE(EnvOverride, WithEnvAndConfig)
+{
+  this->WithEnv::configure("tcp://127.0.0.1:6000");
+  this->WithConfig::configure("unix://some/path");
+
+  shared_ptr<Face> face;
+  BOOST_REQUIRE_NO_THROW(face = make_shared<Face>());
+  BOOST_CHECK(dynamic_pointer_cast<TcpTransport>(face->getTransport()) != nullptr);
+}
+
+BOOST_FIXTURE_TEST_CASE(ExplicitTransport, WithEnvAndConfig)
+{
+  this->WithEnv::configure("wrong-uri");
+  this->WithConfig::configure("wrong-transport:");
+
+  auto transport = make_shared<UnixTransport>("unix://some/path");
+  shared_ptr<Face> face;
+  BOOST_REQUIRE_NO_THROW(face = make_shared<Face>(transport));
+  BOOST_CHECK(dynamic_pointer_cast<UnixTransport>(face->getTransport()) != nullptr);
+}
+
+BOOST_AUTO_TEST_SUITE_END() // CustomizeTransport
 BOOST_AUTO_TEST_SUITE_END() // TestFace
 
 } // namespace tests
diff --git a/tests/unit-tests/security/key-chain.t.cpp b/tests/unit-tests/security/key-chain.t.cpp
index 797ce01..eda972b 100644
--- a/tests/unit-tests/security/key-chain.t.cpp
+++ b/tests/unit-tests/security/key-chain.t.cpp
@@ -42,31 +42,14 @@
 BOOST_FIXTURE_TEST_SUITE(SecurityKeyChain, util::TestHomeEnvironmentFixture)
 
 template<class Path>
-class TestHomeAndPibFixture : public PibDirFixture<Path>
+class TestHomeAndPibFixture : public TestHomeFixture<Path>
 {
 public:
   TestHomeAndPibFixture()
   {
-    setenv("TEST_HOME", this->m_pibDir.c_str(), true);
     unsetenv("NDN_CLIENT_PIB");
     unsetenv("NDN_CLIENT_TPM");
   }
-
-  ~TestHomeAndPibFixture()
-  {
-    unsetenv("TEST_HOME");
-  }
-
-  void
-  createClientConf(std::initializer_list<std::string> lines)
-  {
-    boost::filesystem::create_directories(boost::filesystem::path(this->m_pibDir) / ".ndn");
-    std::ofstream of((boost::filesystem::path(this->m_pibDir) / ".ndn" / "client.conf").c_str());
-    for (auto line : lines) {
-      boost::replace_all(line, "%PATH%", this->m_pibDir);
-      of << line << std::endl;
-    }
-  }
 };
 
 struct PibPathSqlite3File