face: Enable KeyChain customization in DummyClientFace

This feature also required two new Face constructors

Change-Id: I25c6d9d0d94a065176ed348d25e7b99a6c7999c0
Refs: #3435
diff --git a/src/face.cpp b/src/face.cpp
index 51519c9..4d68927 100644
--- a/src/face.cpp
+++ b/src/face.cpp
@@ -66,8 +66,16 @@
   construct(transport, *m_internalKeyChain);
 }
 
-Face::Face(shared_ptr<Transport> transport,
-           boost::asio::io_service& ioService)
+Face::Face(shared_ptr<Transport> transport, KeyChain& keyChain)
+  : m_internalIoService(new boost::asio::io_service())
+  , m_ioService(*m_internalIoService)
+  , m_internalKeyChain(nullptr)
+  , m_impl(new Impl(*this))
+{
+  construct(transport, keyChain);
+}
+
+Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService)
   : m_ioService(ioService)
   , m_internalKeyChain(new KeyChain())
   , m_impl(new Impl(*this))
@@ -75,9 +83,7 @@
   construct(transport, *m_internalKeyChain);
 }
 
-Face::Face(shared_ptr<Transport> transport,
-           boost::asio::io_service& ioService,
-           KeyChain& keyChain)
+Face::Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain)
   : m_ioService(ioService)
   , m_internalKeyChain(nullptr)
   , m_impl(new Impl(*this))
diff --git a/src/face.hpp b/src/face.hpp
index 1fa2aca..fe6af03 100644
--- a/src/face.hpp
+++ b/src/face.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -41,8 +41,8 @@
 namespace boost {
 namespace asio {
 class io_service;
-}
-}
+} // namespace asio
+} // namespace boost
 
 namespace ndn {
 
@@ -54,12 +54,12 @@
 
 namespace security {
 class KeyChain;
-}
+} // namespace security
 using security::KeyChain;
 
 namespace nfd {
 class Controller;
-}
+} // namespace nfd
 
 /**
  * @brief Callback called when expressed Interest gets satisfied with a Data packet
@@ -134,7 +134,7 @@
    * @brief Create a new Face using the default transport (UnixTransport)
    *
    * @throws ConfigFile::Error on configuration file parse failure
-   * @throws Face::Error on unsupported protocol
+   * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
    */
   Face();
 
@@ -162,7 +162,7 @@
    * @param ioService A reference to boost::io_service object that should control all
    *                  IO operations.
    * @throws ConfigFile::Error on configuration file parse failure
-   * @throws Face::Error on unsupported protocol
+   * @throws ConfigFile::Error if configuration file specifies an unsupported protocol
    */
   explicit
   Face(boost::asio::io_service& ioService);
@@ -172,8 +172,6 @@
    *
    * @param host The host of the NDN forwarder
    * @param port (optional) The port or service name of the NDN forwarder (**default**: "6363")
-   *
-   * @throws Face::Error on unsupported protocol
    */
   Face(const std::string& host, const std::string& port = "6363");
 
@@ -182,12 +180,28 @@
    * @param transport the Transport used for communication. If nullptr, then the default
    *                  transport will be used.
    *
-   * @throws Face::Error on unsupported protocol
+   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
+   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
+   *         specifies an unsupported protocol
+   * @note shared_ptr is passed by value because ownership is shared with this class
    */
   explicit
   Face(shared_ptr<Transport> transport);
 
   /**
+   * @brief Create a new Face using the given Transport and KeyChain instance
+   * @param transport the Transport used for communication. If nullptr, then the default
+   *                  transport will be used.
+   * @param keyChain the KeyChain to sign commands
+   *
+   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
+   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
+   *         specifies an unsupported protocol
+   * @note shared_ptr is passed by value because ownership is shared with this class
+   */
+  Face(shared_ptr<Transport> transport, KeyChain& keyChain);
+
+  /**
    * @brief Create a new Face using the given Transport and IO service object
    * @param transport the Transport used for communication. If nullptr, then the default
    *                  transport will be used.
@@ -195,10 +209,12 @@
    *
    * @sa Face(boost::asio::io_service&)
    *
-   * @throws Face::Error on unsupported protocol
+   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
+   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
+   *         specifies an unsupported protocol
+   * @note shared_ptr is passed by value because ownership is shared with this class
    */
-  Face(shared_ptr<Transport> transport,
-       boost::asio::io_service& ioService);
+  Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService);
 
   /**
    * @brief Create a new Face using the given Transport and IO service object
@@ -206,12 +222,13 @@
    *                  transport will be used.
    * @param ioService the io_service that controls all IO operations
    * @param keyChain the KeyChain to sign commands
-   * @throws Face::Error on unsupported protocol
+   *
+   * @throws ConfigFile::Error if @p transport is nullptr on configuration file parse failure
+   * @throws ConfigFile::Error if @p transport is nullptr and the configuration file
+   *         specifies an unsupported protocol
    * @note shared_ptr is passed by value because ownership is shared with this class
    */
-  Face(shared_ptr<Transport> transport,
-       boost::asio::io_service& ioService,
-       KeyChain& keyChain);
+  Face(shared_ptr<Transport> transport, boost::asio::io_service& ioService, KeyChain& keyChain);
 
   ~Face();
 
diff --git a/src/util/dummy-client-face.cpp b/src/util/dummy-client-face.cpp
index 8cdb9dc..cc593ef 100644
--- a/src/util/dummy-client-face.cpp
+++ b/src/util/dummy-client-face.cpp
@@ -89,6 +89,19 @@
 #ifdef NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
   , sentDatas(sentData)
 #endif // NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , m_internalKeyChain(new KeyChain)
+  , m_keyChain(*m_internalKeyChain)
+{
+  this->construct(options);
+}
+
+DummyClientFace::DummyClientFace(KeyChain& keyChain,
+                                 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
+  : Face(make_shared<DummyClientFace::Transport>(), keyChain)
+#ifdef NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , sentDatas(sentData)
+#endif // NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , m_keyChain(keyChain)
 {
   this->construct(options);
 }
@@ -99,6 +112,19 @@
 #ifdef NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
   , sentDatas(sentData)
 #endif // NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , m_internalKeyChain(new KeyChain)
+  , m_keyChain(*m_internalKeyChain)
+{
+  this->construct(options);
+}
+
+DummyClientFace::DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
+                                 const Options& options/* = DummyClientFace::DEFAULT_OPTIONS*/)
+  : Face(make_shared<DummyClientFace::Transport>(), ioService, keyChain)
+#ifdef NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , sentDatas(sentData)
+#endif // NDN_UTIL_DUMMY_FACE_KEEP_DEPRECATED
+  , m_keyChain(keyChain)
 {
   this->construct(options);
 }
@@ -186,8 +212,7 @@
     shared_ptr<Data> data = make_shared<Data>(interest.getName());
     data->setContent(resp.wireEncode());
 
-    KeyChain keyChain;
-    keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
+    m_keyChain.sign(*data, security::SigningInfo(security::SigningInfo::SIGNER_TYPE_SHA256));
 
     this->getIoService().post([this, data] { this->receive(*data); });
   });
diff --git a/src/util/dummy-client-face.hpp b/src/util/dummy-client-face.hpp
index b5ec7d7..c9ea6fc 100644
--- a/src/util/dummy-client-face.hpp
+++ b/src/util/dummy-client-face.hpp
@@ -1,6 +1,6 @@
 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
 /**
- * Copyright (c) 2013-2015 Regents of the University of California.
+ * Copyright (c) 2013-2016 Regents of the University of California.
  *
  * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
  *
@@ -56,9 +56,21 @@
   DummyClientFace(const Options& options = DummyClientFace::DEFAULT_OPTIONS);
 
   /**
+   * @brief Create a dummy face with internal IO service and the specified KeyChain
+   */
+  DummyClientFace(KeyChain& keyChain, const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+
+  /**
    * @brief Create a dummy face with the provided IO service
    */
-  DummyClientFace(boost::asio::io_service& ioService, const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+  DummyClientFace(boost::asio::io_service& ioService,
+                  const Options& options = DummyClientFace::DEFAULT_OPTIONS);
+
+  /**
+   * @brief Create a dummy face with the provided IO service and the specified KeyChain
+   */
+  DummyClientFace(boost::asio::io_service& ioService, KeyChain& keyChain,
+                  const Options& options = DummyClientFace::DEFAULT_OPTIONS);
 
   /** \brief cause the Face to receive a packet
    *  \tparam Packet either Interest or Data
@@ -133,6 +145,10 @@
    *  After .put, .processEvents must be called before this signal would be emitted.
    */
   Signal<DummyClientFace, lp::Nack> onSendNack;
+
+private:
+  std::unique_ptr<KeyChain> m_internalKeyChain;
+  KeyChain& m_keyChain;
 };
 
 template<>