/** @file $Id$ $Date$ $Author$ @copy © Marc Wäckerlin @license LGPL, see file COPYING $Log$ Revision 1.2 2005/04/07 20:42:38 marc renamed loggerhierarchy from mrw.gccfunctiontrace to mrw.fn Revision 1.1 2005/03/11 21:07:55 marc initial version 1 2 3 4 5 6 7 8 5678901234567890123456789012345678901234567890123456789012345678901234567890 */ #include #include #include #include #include #include #include #include #include #include #include namespace HalloWelt { class A { public: void method() { } }; void fn() { A().method(); A().method(); } void fn1() { fn(); fn(); } } void anotherFunction() { HalloWelt::fn1(); } #ifdef _REENTRANT #include //#include // 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(); #ifdef _REENTRANT try {mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log");} #else try {mrw::File::remove("mrwautofunctiontracelog4cxx_test.log");} #endif catch (...) {} log4cxx::helpers::Properties properties; properties.setProperty("log4j.rootLogger", "OFF, A1"); properties.setProperty("log4j.logger.mrw.fn", "DEBUG"); properties.setProperty("log4j.logger.mrw.fn.log4cxx", "OFF"); properties.setProperty("log4j.logger.mrw.fn.boost", "OFF"); properties.setProperty("log4j.logger.mrw.fn.Thread", "OFF"); properties.setProperty("log4j.logger.mrw.fn.mrw", "OFF"); properties.setProperty("log4j.logger.mrw.fn.std", "OFF"); properties.setProperty("log4j.logger.mrw.fn.new", "OFF"); properties.setProperty("log4j.logger.mrw.fn.CppUnit", "OFF"); properties.setProperty("log4j.logger.mrw.fn.__gnu_cxx", "OFF"); properties.setProperty("log4j.appender.A1", "org.apache.log4j.FileAppender"); properties.setProperty("log4j.appender.A1.layout", "org.apache.log4j.PatternLayout"); #ifdef _REENTRANT properties.setProperty("log4j.appender.A1.layout.ConversionPattern", "%t-%-27c%m%n"); properties.setProperty("log4j.appender.A1.filename", "mrwautofunctiontracelog4cxx_test-mt.log"); #else properties.setProperty("log4j.appender.A1.layout.ConversionPattern", "%-27c%m%n"); properties.setProperty("log4j.appender.A1.filename", "mrwautofunctiontracelog4cxx_test.log"); #endif log4cxx::PropertyConfigurator::configure(properties); #ifdef _REENTRANT // 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(); #ifdef _REENTRANT thread1.join(); thread2.join(); thread3.join(); #endif } void checkfile() { mrw::RegExp match ("^mrw\\.fn\\.anotherFunction ( ? ? ?)\\\\ anotherFunction\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn1 \\1 \\\\ HalloWelt::fn1\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn \\1 \\\\ HalloWelt::fn\\(\\)\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" "mrw\\.fn\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn \\1 / HalloWelt::fn\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn \\1 \\\\ HalloWelt::fn\\(\\)\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" "mrw\\.fn\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn \\1 / HalloWelt::fn\\(\\)\n" "mrw\\.fn\\.HalloWelt\\.fn1 \\1 / HalloWelt::fn1\\(\\)\n" "mrw\\.fn\\.anotherFunction \\1/ anotherFunction\\(\\)\n$"); #ifdef _REENTRANT std::string log(mrw::File::read("mrwautofunctiontracelog4cxx_test-mt.log")); std::map logs; 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)); CPPUNIT_ASSERT(dash!=std::string::npos); logs[mrw::to(log.substr(last, dash-last))] += log.substr(dash+1, pos-dash); } CPPUNIT_ASSERT(logs.size()==4); // 4 threads for (std::map::iterator it(logs.begin()); it!=logs.end(); ++it) CPPUNIT_ASSERT(match(it->second)); mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log"); #else CPPUNIT_ASSERT(match(mrw::File::read("mrwautofunctiontracelog4cxx_test.log"))); 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; }