/** @file
$ Id $
$ Date $
$ Author $
@ copy & copy ; Marc W & auml ; ckerlin
@ license LGPL , see file < a href = " license.html " > COPYING < / a >
$ 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 <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>
# include <mrw/file.hpp>
# include <mrw/regexp.hpp>
# include <mrw/string.hpp>
# include <mrw/stacktrace.hpp>
# include <map>
namespace HalloWelt {
class A {
public :
void method ( ) {
}
} ;
void fn ( ) {
A ( ) . method ( ) ;
A ( ) . method ( ) ;
}
void fn1 ( ) {
fn ( ) ;
fn ( ) ;
}
}
void anotherFunction ( ) {
HalloWelt : : fn1 ( ) ;
}
# ifdef _REENTRANT
# include <boost/thread/thread.hpp>
//#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 ( ) ;
# 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 < unsigned long , std : : string > 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 < unsigned long > ( log . substr ( last , dash - last ) ) ] + =
log . substr ( dash + 1 , pos - dash ) ;
}
CPPUNIT_ASSERT ( logs . size ( ) = = 4 ) ; // 4 threads
for ( std : : map < unsigned long , std : : string > : : 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 ;
}