00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/test/TestBase.h"
00026 #include "fennel/common/FileSystem.h"
00027 #include "fennel/common/Backtrace.h"
00028 #include "boost/test/test_tools.hpp"
00029
00030 using namespace fennel;
00031 using boost::unit_test::test_unit;
00032
00033 ConfigMap TestBase::configMap;
00034 bool TestBase::runAll = false;
00035 std::string TestBase::runSingle;
00036
00037 ParamName TestBase::paramTestSuiteName = "testSuiteNameBoost";
00038 ParamName TestBase::paramTraceFileName = "testTraceFileName";
00039 ParamName TestBase::paramDictionaryFileName = "testDictionaryFileName";
00040 ParamName TestBase::paramTraceLevel = "testTraceLevel";
00041 ParamName TestBase::paramStatsFileName = "testStatsFileName";
00042 ParamName TestBase::paramTraceStdout = "testTraceStdout";
00043 ParamName TestBase::paramDegreeOfParallelism = "degreeOfParallelism";
00044
00045 TestBase::TestBase()
00046 : statsTarget(
00047 configMap.getStringParam(paramStatsFileName,"/tmp/fennel.stats")),
00048 statsTimer(statsTarget,500),
00049 defaultTests(),
00050 extraTests()
00051 {
00052 pTestObj.reset(this);
00053 testName = configMap.getStringParam(paramTestSuiteName);
00054 traceLevel = static_cast<TraceLevel>(
00055 configMap.getIntParam(paramTraceLevel,TRACE_CONFIG));
00056 std::string traceStdoutParam =
00057 configMap.getStringParam(paramTraceStdout,"");
00058 traceStdout = ((traceStdoutParam.length() == 0) ? false : true);
00059
00060 std::string defaultTraceFileName;
00061 const char *fennelHome = getenv("FENNEL_HOME");
00062 if (fennelHome) {
00063 defaultTraceFileName += fennelHome;
00064 defaultTraceFileName += "/trace/";
00065 }
00066 defaultTraceFileName += testName + "_trace.log";
00067 std::string traceFileName =
00068 configMap.getStringParam(
00069 paramTraceFileName,
00070 defaultTraceFileName);
00071
00072 traceFile = false;
00073 if (traceFileName == "-") {
00074 traceStdout = true;
00075 } else if (traceFileName != "none") {
00076 if (!traceFileName.empty()) {
00077 traceStream.open(traceFileName.c_str());
00078 if (traceStream.good()) {
00079 traceFile = true;
00080 }
00081 }
00082 }
00083
00084
00085
00086
00087
00088
00089 configMap.initTraceSource(shared_from_this(), "testConfig");
00090 }
00091
00092 TestBase::~TestBase()
00093 {
00094 traceStream.close();
00095 configMap.clear();
00096 }
00097
00098
00107
00108 void TestBase::readParams(int argc,char **argv)
00109 {
00110 bool verbose = false;
00111 ConfigMap adhocMap;
00112
00113 for (int i = 1; i < argc; ++i) {
00114 std::string arg = argv[i];
00115 if (argv[i][0] == '-') {
00116 if (arg == "-v") {
00117 verbose = true;
00118 } else if (arg == "-") {
00119 configMap.readParams(std::cin);
00120 } else if (arg == "-all") {
00121 runAll = true;
00122 } else if (arg == "-t") {
00123 permAssert(i + 1 < argc);
00124 runSingle = argv[++i];
00125 } else if (arg[1] == 't') {
00126 runSingle = arg.substr(2);
00127 }
00128 } else {
00129 int i = arg.find("=");
00130 if ((0 < i) && (i < arg.size())) {
00131
00132 std::string key = arg.substr(0,i);
00133 std::string val = arg.substr(i + 1);
00134 adhocMap.setStringParam(key,val);
00135 } else {
00136
00137 std::ifstream configFile(arg.c_str());
00138 assert(configFile.good());
00139 configMap.readParams(configFile);
00140 }
00141 }
00142 }
00143 configMap.mergeFrom(adhocMap);
00144
00145
00146
00147 if (!configMap.isParamSet(paramDictionaryFileName)) {
00148 std::string dictFileName = "dictWords";
00149 configMap.setStringParam(paramDictionaryFileName,dictFileName);
00150 }
00151
00152 if (verbose) {
00153 configMap.dumpParams(std::cout);
00154 }
00155 }
00156
00157 TestSuite *TestBase::releaseTestSuite()
00158 {
00159 assert(pTestObj);
00160 assert(pTestObj.use_count() > 1);
00161
00162
00163 pTestObj.reset();
00164
00165 TestSuite* pTestSuite = BOOST_TEST_SUITE(testName.c_str());
00166
00167 if (runSingle.size()) {
00168 test_unit *p = defaultTests.findTest(runSingle);
00169 if (!p) {
00170 p = extraTests.findTest(runSingle);
00171 }
00172 if (!p) {
00173 std::cerr << "test " << runSingle << " not found\n";
00174 exit(2);
00175 }
00176 pTestSuite->add(p);
00177 } else {
00178 defaultTests.addAllToTestSuite(pTestSuite);
00179 if (runAll) {
00180 extraTests.addAllToTestSuite(pTestSuite);
00181 }
00182 }
00183 return pTestSuite;
00184 }
00185
00186 void TestBase::TestCaseGroup::addTest(std::string name, test_unit *tu)
00187 {
00188 items.push_back(Item(name, tu));
00189 }
00190
00191 test_unit*
00192 TestBase::TestCaseGroup::findTest(std::string name) const
00193 {
00194 for (std::vector<Item>::const_iterator p = items.begin();
00195 p != items.end(); ++p)
00196 {
00197 if (name == p->name) {
00198 return p->tu;
00199 }
00200 }
00201 return 0;
00202 }
00203
00204 void TestBase::TestCaseGroup::addAllToTestSuite(TestSuite *suite) const
00205 {
00206 for (std::vector<Item>::const_iterator p = items.begin();
00207 p != items.end(); ++p)
00208 {
00209 suite->add(p->tu);
00210 }
00211 }
00212
00213
00214 void TestBase::beforeTestCase(std::string testCaseName)
00215 {
00216 notifyTrace(testName,TRACE_INFO,"ENTER: " + testCaseName);
00217
00218
00219
00220
00221
00222 AutoBacktrace::setOutputStream();
00223 AutoBacktrace::setTraceTarget(shared_from_this());
00224 AutoBacktrace::install();
00225 configMap.initTraceSource(shared_from_this(), "testConfig");
00226 }
00227
00228 void TestBase::afterTestCase(std::string testCaseName)
00229 {
00230 AutoBacktrace::setTraceTarget();
00231 configMap.disableTracing();
00232 notifyTrace(testName,TRACE_INFO,"LEAVE: " + testCaseName);
00233 }
00234
00235 void TestBase::testCaseSetUp()
00236 {
00237 }
00238
00239 void TestBase::testCaseTearDown()
00240 {
00241 }
00242
00243 void TestBase::notifyTrace(std::string source,TraceLevel,std::string message)
00244 {
00245 if (traceFile || traceStdout) {
00246 StrictMutexGuard traceMutexGuard(traceMutex);
00247 if (traceFile) {
00248 traceStream << "[" << source << "] " << message << std::endl;
00249 traceStream.flush();
00250 }
00251 if (traceStdout) {
00252 std::cout << "[" << source << "] " << message << std::endl;
00253 std::cout.flush();
00254 }
00255 }
00256 }
00257
00258 TraceLevel TestBase::getSourceTraceLevel(std::string)
00259 {
00260 return traceLevel;
00261 }
00262
00263 void TestBase::snooze(uint nSeconds)
00264 {
00265 #ifdef __MSVC__
00266 ::_sleep(nSeconds*1000);
00267 #else
00268 ::sleep(nSeconds);
00269 #endif
00270 }
00271
00272