fw: FaceTable onAdd,onRemove events

refs #1244

Change-Id: I8710dedaba94c1fcd852bd3aa2f21d39ad0bd7ee
diff --git a/daemon/fw/face-table.cpp b/daemon/fw/face-table.cpp
index 1ed79ad..35bf377 100644
--- a/daemon/fw/face-table.cpp
+++ b/daemon/fw/face-table.cpp
@@ -36,11 +36,15 @@
                                   &m_forwarder, boost::ref(*face), _1);
   face->onFail            += bind(&FaceTable::remove,
                                   this, face);
+
+  this->onAdd(face);
 }
 
 void
 FaceTable::remove(shared_ptr<Face> face)
 {
+  this->onRemove(face);
+
   FaceId faceId = face->getId();
   m_faces.erase(faceId);
   face->setId(INVALID_FACEID);
diff --git a/daemon/fw/face-table.hpp b/daemon/fw/face-table.hpp
index 2af2b6b..868cf9e 100644
--- a/daemon/fw/face-table.hpp
+++ b/daemon/fw/face-table.hpp
@@ -48,6 +48,17 @@
   const_iterator
   end() const;
 
+public: // events
+  /** \brief fires after a Face is added
+   */
+  EventEmitter<shared_ptr<Face> > onAdd;
+
+  /** \brief fires before a Face is removed
+   *
+   *  FaceId is valid when this event is fired
+   */
+  EventEmitter<shared_ptr<Face> > onRemove;
+
 private:
   // remove is private because it's a subscriber of face.onFail event.
   // face->close() closes a face and would trigger .remove(face)
diff --git a/tests/fw/face-table.cpp b/tests/fw/face-table.cpp
index b07995f..492d633 100644
--- a/tests/fw/face-table.cpp
+++ b/tests/fw/face-table.cpp
@@ -15,10 +15,22 @@
 
 BOOST_FIXTURE_TEST_SUITE(FwFaceTable, BaseFixture)
 
+static inline void
+saveFaceId(std::vector<FaceId>& faceIds, shared_ptr<Face> face)
+{
+  faceIds.push_back(face->getId());
+}
+
 BOOST_AUTO_TEST_CASE(AddRemove)
 {
   Forwarder forwarder;
 
+  FaceTable& faceTable = forwarder.getFaceTable();
+  std::vector<FaceId> onAddHistory;
+  std::vector<FaceId> onRemoveHistory;
+  faceTable.onAdd    += bind(&saveFaceId, boost::ref(onAddHistory   ), _1);
+  faceTable.onRemove += bind(&saveFaceId, boost::ref(onRemoveHistory), _1);
+
   shared_ptr<Face> face1 = make_shared<DummyFace>();
   shared_ptr<Face> face2 = make_shared<DummyFace>();
 
@@ -32,11 +44,16 @@
   BOOST_CHECK_NE(face2->getId(), INVALID_FACEID);
   BOOST_CHECK_NE(face1->getId(), face2->getId());
 
+  BOOST_REQUIRE_EQUAL(onAddHistory.size(), 2);
+  BOOST_CHECK_EQUAL(onAddHistory[0], face1->getId());
+  BOOST_CHECK_EQUAL(onAddHistory[1], face2->getId());
+
   face1->close();
-  face2->close();
 
   BOOST_CHECK_EQUAL(face1->getId(), INVALID_FACEID);
-  BOOST_CHECK_EQUAL(face2->getId(), INVALID_FACEID);
+
+  BOOST_REQUIRE_EQUAL(onRemoveHistory.size(), 1);
+  BOOST_CHECK_EQUAL(onRemoveHistory[0], onAddHistory[0]);
 }
 
 BOOST_AUTO_TEST_CASE(Enumerate)