From 8e05d5a1ef46e6c8b1321882b638abf4f0919a77 Mon Sep 17 00:00:00 2001
From: Marco Biasini <marco.biasini@unibas.ch>
Date: Wed, 12 Oct 2011 15:56:50 +0200
Subject: [PATCH] added GetCurrentLogSink()

---
 modules/base/pymod/export_logger.cc | 17 +++++++++---
 modules/base/src/log_sink.hh        |  2 +-
 modules/base/tests/CMakeLists.txt   |  1 +
 modules/base/tests/test_log.py      | 42 +++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 4 deletions(-)
 create mode 100644 modules/base/tests/test_log.py

diff --git a/modules/base/pymod/export_logger.cc b/modules/base/pymod/export_logger.cc
index 4aa1dadc8..c76589d60 100644
--- a/modules/base/pymod/export_logger.cc
+++ b/modules/base/pymod/export_logger.cc
@@ -25,7 +25,11 @@ using namespace boost::python;
 
 using namespace ost;
 
-struct WrappedLogSink : public LogSink {
+struct PyLogSink: public LogSink {
+
+};
+
+struct WrappedLogSink : public PyLogSink, public wrapper<PyLogSink> {
   WrappedLogSink(PyObject* self): self_(self)
   { }
   virtual void LogMessage(const String& message , int severity) 
@@ -73,6 +77,10 @@ void pop_log_sink()
   Logger::Instance().PopSink();
 }
 
+LogSinkPtr get_log_sink()
+{
+  return Logger::Instance().GetCurrentSink();
+}
 
 void log_error(const String& m) {LOG_ERROR(m);}
 void log_warning(const String& m) {LOG_WARNING(m);}
@@ -88,11 +96,13 @@ void reset_sinks()
 
 void export_Logger()
 {
-  class_<LogSink, WrappedLogSinkPtr, 
+  class_<LogSink, LogSinkPtr, boost::noncopyable>("_LogSink", no_init)
+    .def("LogMessage", &LogSink::LogMessage)
+  ;
+  class_<PyLogSink, WrappedLogSinkPtr, bases<LogSink>,
          boost::noncopyable>("LogSink")
     .def("LogMessage", &WrappedLogSink::LogMessageDefault)
   ;
-
   class_<MultiLogSink, MultiLogSinkPtr, bases<LogSink>, 
          boost::noncopyable >("MultiLogSink", init<>())
     .def("AddSink",&MultiLogSink::AddSink)
@@ -109,6 +119,7 @@ void export_Logger()
   def("PopVerbosityLevel",pop_verb);
   def("GetVerbosityLevel",get_verb);
   def("PushLogSink",push_log_sink);
+  def("GetCurrentLogSink",get_log_sink);
   def("PopLogSink",pop_log_sink);
   def("LogError",log_error);
   def("LogWarning",log_warning);
diff --git a/modules/base/src/log_sink.hh b/modules/base/src/log_sink.hh
index f4b14d007..6cf939201 100644
--- a/modules/base/src/log_sink.hh
+++ b/modules/base/src/log_sink.hh
@@ -35,7 +35,7 @@ class DLLEXPORT LogSink {
 public:
   LogSink(){};
   virtual ~LogSink() { }
-  virtual void LogMessage(const String& message, int severity=0)=0;
+  virtual void LogMessage(const String& message, int severity=0) {};
 };
 
 typedef boost::shared_ptr<LogSink> LogSinkPtr;
diff --git a/modules/base/tests/CMakeLists.txt b/modules/base/tests/CMakeLists.txt
index c18fcda10..5a5bce51a 100644
--- a/modules/base/tests/CMakeLists.txt
+++ b/modules/base/tests/CMakeLists.txt
@@ -4,6 +4,7 @@ set(OST_BASE_UNIT_TESTS
   test_pod_vector.cc
   test_stutil.py
   test_table.py
+  test_log.py
   tests.cc
 )
 
diff --git a/modules/base/tests/test_log.py b/modules/base/tests/test_log.py
new file mode 100644
index 000000000..7ea86c5bc
--- /dev/null
+++ b/modules/base/tests/test_log.py
@@ -0,0 +1,42 @@
+import unittest
+import ost
+
+# Altough the logging system might appear to be too simple to be worth writing a 
+# specific test case for, it actually isn't. The python export is very fragile 
+# and seemingly trivial changes can break the code in unexpected ways. So let's 
+# check for some invariants
+class TestLog(unittest.TestCase):
+  def testGetLogSink(self):
+    logsink=ost.GetCurrentLogSink()
+    self.assertTrue(hasattr(logsink, 'LogMessage'))
+    # Check if the return type of logsink is sane
+    ost.PushLogSink(ost.GetCurrentLogSink())
+  def testPushPopLogSink(self):
+    class MyLogSink(ost.LogSink):
+       def __init__(self):
+         ost.LogSink.__init__(self)
+    ls=MyLogSink()
+    ost.PushLogSink(ls)
+    self.assertEqual(ls, ost.GetCurrentLogSink())
+    ost.PopLogSink()
+    self.assertNotEqual(ls, ost.GetCurrentLogSink())
+
+  def testLogMessage(self):
+    class CapturingLogSink(ost.LogSink):
+      def __init__(self):
+        ost.LogSink.__init__(self)
+      def LogMessage(self, message, severity):
+        self.message=message
+        self.severity=severity
+        ost.PushLogSink(ls)
+    ls=CapturingLogSink()
+    ost.PushLogSink(ls)
+    ost.LogError('error message')
+    self.assertEqual(ls.message, 'error message\n')
+    self.assertEqual(ls.severity, 0)
+    ost.PopLogSink()
+if __name__ == "__main__":
+  try:
+    unittest.main()
+  except Exception, e:
+    print e
\ No newline at end of file
-- 
GitLab