C++ Library containing a lot of needful things: Stack Trace, Command Line Parser, Resource Handling, Configuration Files, Unix Command Execution, Directories, Regular Expressions, Tokenizer, Function Trace, Standard Extensions.
 
 
 
 
 

179 lines
6.8 KiB

/** @file
$Id$
$Date$
$Author$
@copy © Marc Wäckerlin
@license LGPL, see file <a href="license.html">COPYING</a>
$Log$
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.gccfunctiontrace",
"DEBUG");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.log4cxx",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.boost",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.Thread",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.mrw",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.std",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.new",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.CppUnit",
"OFF");
properties.setProperty("log4j.logger.mrw.gccfunctiontrace.__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-%-41c%m%n");
properties.setProperty("log4j.appender.A1.filename",
"mrwautofunctiontracelog4cxx_test-mt.log");
#else
properties.setProperty("log4j.appender.A1.layout.ConversionPattern",
"%-41c%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\\.gccfunctiontrace\\.anotherFunction ( ? ? ?)\\\\ anotherFunction\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn1 \\1 \\\\ HalloWelt::fn1\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn \\1 \\\\ HalloWelt::fn\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 \\\\ HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 \\\\ HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn \\1 / HalloWelt::fn\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn \\1 \\\\ HalloWelt::fn\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 \\\\ HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 \\\\ HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.A\\.method \\1 / HalloWelt::A::method\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn \\1 / HalloWelt::fn\\(\\)\n"
"mrw\\.gccfunctiontrace\\.HalloWelt\\.fn1 \\1 / HalloWelt::fn1\\(\\)\n"
"mrw\\.gccfunctiontrace\\.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;
}