/** @file $Id$ $Date$ $Author$ @copy © Marc Wäckerlin @license LGPL, see file COPYING $Log$ Revision 1.3 2005/11/29 12:39:42 marc make it compilable with gcc 4.0.2 and newer doxygen 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 #if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) && _REENTRANT && !_MT #define _MT #endif namespace HalloWelt { class A { public: void method() { } }; void fn(int) { A().method(); A().method(); } void fn1() { fn(1); fn(2); } } void anotherFunction() { HalloWelt::fn1(); } #ifdef _MT #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 _MT try {mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log");} #else try {mrw::File::remove("mrwautofunctiontracelog4cxx_test.log");} #endif catch (...) {} log4cxx::helpers::Properties properties; 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()))); #ifdef _MT 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()))); #else 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()))); #endif log4cxx::PropertyConfigurator::configure(properties); #ifdef _MT // 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 _MT 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\\(int\\)\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\\(int\\)\n" "mrw\\.fn\\.HalloWelt\\.fn \\1 \\\\ HalloWelt::fn\\(int\\)\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\\(int\\)\n" "mrw\\.fn\\.HalloWelt\\.fn1 \\1 / HalloWelt::fn1\\(\\)\n" "mrw\\.fn\\.anotherFunction \\1/ anotherFunction\\(\\)\n$"); #ifdef _MT std::string log(mrw::File::read("mrwautofunctiontracelog4cxx_test-mt.log")); typedef std::map Logs; Logs 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_MESSAGE("\"-\" not found", dash!=std::string::npos); logs[mrw::to(log.substr(last, dash-last))] += log.substr(dash+1, pos-dash); } 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)); mrw::File::remove("mrwautofunctiontracelog4cxx_test-mt.log"); #else 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"))); 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; }