| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | /** @file
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $Id$ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $Date$ | 
					
						
							|  |  |  |     $Author$ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @copy © Marc Wäckerlin | 
					
						
							|  |  |  |     @license LGPL, see file <a href="license.html">COPYING</a> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     $Log$ | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |     Revision 1.3  2005/11/29 12:39:42  marc | 
					
						
							|  |  |  |     make it compilable with gcc 4.0.2 and newer doxygen | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-07 20:42:38 +00:00
										 |  |  |     Revision 1.2  2005/04/07 20:42:38  marc | 
					
						
							|  |  |  |     renamed loggerhierarchy from mrw.gccfunctiontrace to mrw.fn | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |     Revision 1.1  2005/03/11 21:07:55  marc | 
					
						
							|  |  |  |     initial version | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          1         2         3         4         5         6         7         8 | 
					
						
							|  |  |  |     5678901234567890123456789012345678901234567890123456789012345678901234567890 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <log4cxx/propertyconfigurator.h>
 | 
					
						
							|  |  |  | #include <log4cxx/helpers/properties.h>
 | 
					
						
							|  |  |  | #include <cppunit/TestFixture.h>
 | 
					
						
							|  |  |  | #include <cppunit/ui/text/TestRunner.h>
 | 
					
						
							|  |  |  | #include <cppunit/extensions/HelperMacros.h>
 | 
					
						
							|  |  |  | #include <cppunit/extensions/TestFactoryRegistry.h>
 | 
					
						
							| 
									
										
										
										
											2011-12-10 11:39:09 +00:00
										 |  |  | #include <mrw/file.hxx>
 | 
					
						
							|  |  |  | #include <mrw/regexp.hxx>
 | 
					
						
							|  |  |  | #include <mrw/string.hxx>
 | 
					
						
							|  |  |  | #include <mrw/stacktrace.hxx>
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | #include <map>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-08-20 16:09:31 +00:00
										 |  |  | #if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) \
 | 
					
						
							|  |  |  |   && defined(_REENTRANT) && !defined(_MT) | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #define _MT
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | namespace HalloWelt { | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |   class A { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |       void method() { | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |   void fn(int) { | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |     A().method(); | 
					
						
							|  |  |  |     A().method(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   void fn1() { | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |     fn(1); | 
					
						
							|  |  |  |     fn(2); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void anotherFunction() { | 
					
						
							|  |  |  |   HalloWelt::fn1(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2011-12-10 11:39:09 +00:00
										 |  |  | #include <boost/thread/thread.hxx>
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | //#include <unistd.h> // sleep, the one from boost::thread does not work!
 | 
					
						
							|  |  |  | class Thread { | 
					
						
							|  |  |  |   public: | 
					
						
							|  |  |  |     void operator()() { | 
					
						
							|  |  |  |       anotherFunction(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace mrw { | 
					
						
							|  |  |  |   class AutoFunctionTraceLog4CxxTest: public CppUnit::TestFixture { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |       void testcase() { | 
					
						
							|  |  |  |         mrw::StackTrace::createSymtable(); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         try {mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log");} | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  |         try {mrw::File::remove("mrwautofunctiontracelog4cxx_test.log");} | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         catch (...) {} | 
					
						
							|  |  |  |         log4cxx::helpers::Properties properties; | 
					
						
							| 
									
										
										
										
											2007-08-05 08:20:01 +00:00
										 |  |  |         std::string name, cont; | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.rootLogger", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF, A1", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="DEBUG", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.global", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.allocator", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.std.*", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.log4cxx", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.boost", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.Thread", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.mrw", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.std", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.new", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.CppUnit", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.logger.mrw.fn.__gnu_cxx", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="OFF", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.appender.A1", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="org.apache.log4j.FileAppender", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.appender.A1.layout", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="org.apache.log4j.PatternLayout", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2007-08-05 08:20:01 +00:00
										 |  |  |         properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="%t-%-27c%m%n", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.appender.A1.filename", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="mrwautofunctiontracelog4cxx_test-mt.log", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2007-08-05 08:20:01 +00:00
										 |  |  |         properties.setProperty((name="log4j.appender.A1.layout.ConversionPattern", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="%-27c%m%n", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							|  |  |  |         properties.setProperty((name="log4j.appender.A1.filename", | 
					
						
							|  |  |  |                                 log4cxx::String(name.begin(), name.end())), | 
					
						
							|  |  |  |                                (cont="mrwautofunctiontracelog4cxx_test.log", | 
					
						
							|  |  |  |                                 log4cxx::String(cont.begin(), cont.end()))); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  |         log4cxx::PropertyConfigurator::configure(properties); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         // sleep(4); // to be reproducable, wait for "main" flag
 | 
					
						
							|  |  |  |         Thread threadFunction; | 
					
						
							|  |  |  |         boost::thread::thread thread1(threadFunction); | 
					
						
							|  |  |  |         boost::thread::thread thread2(threadFunction); | 
					
						
							|  |  |  |         boost::thread::thread thread3(threadFunction); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |         anotherFunction(); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         thread1.join(); | 
					
						
							|  |  |  |         thread2.join(); | 
					
						
							|  |  |  |         thread3.join(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       void checkfile() { | 
					
						
							|  |  |  |         mrw::RegExp match | 
					
						
							| 
									
										
										
										
											2005-04-07 20:42:38 +00:00
										 |  |  |           ("^mrw\\.fn\\.anotherFunction     ( ? ? ?)\\\\ anotherFunction\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.fn1       \\1 \\\\ HalloWelt::fn1\\(\\)\n" | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.fn        \\1  \\\\ HalloWelt::fn\\(int\\)\n" | 
					
						
							| 
									
										
										
										
											2005-04-07 20:42:38 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   \\\\ HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   / HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   \\\\ HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   / HalloWelt::A::method\\(\\)\n" | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.fn        \\1  / HalloWelt::fn\\(int\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.fn        \\1  \\\\ HalloWelt::fn\\(int\\)\n" | 
					
						
							| 
									
										
										
										
											2005-04-07 20:42:38 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   \\\\ HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   / HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   \\\\ HalloWelt::A::method\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.HalloWelt\\.A\\.method  \\1   / HalloWelt::A::method\\(\\)\n" | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.fn        \\1  / HalloWelt::fn\\(int\\)\n" | 
					
						
							| 
									
										
										
										
											2005-04-07 20:42:38 +00:00
										 |  |  |            "mrw\\.fn\\.HalloWelt\\.fn1       \\1 / HalloWelt::fn1\\(\\)\n" | 
					
						
							|  |  |  |            "mrw\\.fn\\.anotherFunction     \\1/ anotherFunction\\(\\)\n$"); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  | #ifdef _MT
 | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         std::string log(mrw::File::read("mrwautofunctiontracelog4cxx_test-mt.log")); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |         typedef std::map<unsigned long, std::string> Logs; | 
					
						
							|  |  |  |         Logs logs; | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         for (std::string::size_type pos(0), last(0); | 
					
						
							|  |  |  |              (pos=log.find('\n', pos+1))!=std::string::npos; last=pos) { | 
					
						
							|  |  |  |           std::string::size_type dash(log.find('-', last)); | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |           CPPUNIT_ASSERT_MESSAGE("\"-\" not found", | 
					
						
							|  |  |  |                                  dash!=std::string::npos); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |           logs[mrw::to<unsigned long>(log.substr(last, dash-last))] += | 
					
						
							|  |  |  |             log.substr(dash+1, pos-dash); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |         CPPUNIT_ASSERT_EQUAL((Logs::size_type)4, logs.size()); // 4 threads
 | 
					
						
							|  |  |  |         for (Logs::iterator it(logs.begin()); it!=logs.end(); ++it) | 
					
						
							|  |  |  |           CPPUNIT_ASSERT_MESSAGE("The following text does not match the " | 
					
						
							|  |  |  |                                  "Expectation:\n--------------------\n" | 
					
						
							|  |  |  |                                  +it->second+"--------------------", | 
					
						
							|  |  |  |                                  match(it->second)); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log"); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2005-11-29 12:42:01 +00:00
										 |  |  |         CPPUNIT_ASSERT_MESSAGE | 
					
						
							|  |  |  |           ("The following text does not match the " | 
					
						
							|  |  |  |            "Expectation:\n--------------------\n" | 
					
						
							|  |  |  |            +mrw::File::read("mrwautofunctiontracelog4cxx_test.log") | 
					
						
							|  |  |  |            +"--------------------", | 
					
						
							|  |  |  |            match(mrw::File::read("mrwautofunctiontracelog4cxx_test.log"))); | 
					
						
							| 
									
										
										
										
											2005-03-11 21:07:55 +00:00
										 |  |  |         mrw::File::remove("mrwautofunctiontracelog4cxx_test.log"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       CPPUNIT_TEST_SUITE(AutoFunctionTraceLog4CxxTest); | 
					
						
							|  |  |  |       CPPUNIT_TEST(testcase); | 
					
						
							|  |  |  |       CPPUNIT_TEST(checkfile); | 
					
						
							|  |  |  |       CPPUNIT_TEST_SUITE_END(); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   CPPUNIT_TEST_SUITE_REGISTRATION(AutoFunctionTraceLog4CxxTest); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int main() { | 
					
						
							|  |  |  |   CppUnit::TextUi::TestRunner runner; | 
					
						
							|  |  |  |   runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); | 
					
						
							|  |  |  |   return runner.run() ? 0 : 1; | 
					
						
							|  |  |  | } |