/*========================================================================= Program: Insight Segmentation & Registration Toolkit Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2002 Insight Consortium. All rights reserved. See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include #include "ctest.h" #include "cmRegularExpression.h" bool TryExecutable(const char *dir, const char *file, std::string *fullPath, const char *subdir) { // try current directory std::string tryPath; if (dir && strcmp(dir,"")) { tryPath = dir; tryPath += "/"; } if (subdir && strcmp(subdir,"")) { tryPath += subdir; tryPath += "/"; } tryPath += file; if(cmSystemTools::FileExists(tryPath.c_str())) { *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); return true; } tryPath += cmSystemTools::GetExecutableExtension(); if(cmSystemTools::FileExists(tryPath.c_str())) { *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str()); return true; } return false; } std::string ctest::FindExecutable(const char *exe) { std::string fullPath = ""; std::string dir; std::string file; cmSystemTools::SplitProgramPath(exe, dir, file); if(m_ConfigType != "") { if(TryExecutable(dir.c_str(), file.c_str(), &fullPath, m_ConfigType.c_str())) { return fullPath; } std::string tried = dir; dir += "/"; dir += m_ConfigType; dir += "/"; dir += file; cmSystemTools::Error("config type specified on the command line, but test executable not found.", dir.c_str()); return ""; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,".")) { return fullPath; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"")) { return fullPath; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release")) { return fullPath; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug")) { return fullPath; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel")) { return fullPath; } if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo")) { return fullPath; } // if everything else failed, check the users path if (dir != "") { std::string path = cmSystemTools::FindProgram(file.c_str()); if (path != "") { return path; } } return fullPath; } void ctest::ProcessDirectory(int &passed, std::vector &failed) { // does the DartTestfile.txt exist ? if(!cmSystemTools::FileExists("DartTestfile.txt")) { return; } // parse the file std::ifstream fin("DartTestfile.txt"); if(!fin) { return; } std::string name; std::vector args; cmRegularExpression ireg(this->m_IncludeRegExp.c_str()); cmRegularExpression ereg(this->m_ExcludeRegExp.c_str()); cmRegularExpression dartStuff("([\t\n ]*[\t ]*[\n]*)"); bool parseError; while ( fin ) { if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt", parseError)) { if (name == "SUBDIRS") { std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); for(std::vector::iterator j = args.begin(); j != args.end(); ++j) { std::string nwd = cwd + "/"; nwd += *j; if (cmSystemTools::FileIsDirectory(nwd.c_str())) { std::cerr << "Changing directory into " << nwd.c_str() << "\n"; cmSystemTools::ChangeDirectory(nwd.c_str()); this->ProcessDirectory(passed, failed); } } // return to the original directory cmSystemTools::ChangeDirectory(cwd.c_str()); } if (name == "ADD_TEST") { if (this->m_UseExcludeRegExp && this->m_UseExcludeRegExpFirst && ereg.find(args[0].c_str())) { continue; } if (this->m_UseIncludeRegExp && !ireg.find(args[0].c_str())) { continue; } if (this->m_UseExcludeRegExp && !this->m_UseExcludeRegExpFirst && ereg.find(args[0].c_str())) { continue; } fprintf(stderr,"Testing %-30s ",args[0].c_str()); fflush(stderr); //std::cerr << "Testing " << args[0] << " ... "; // find the test executable std::string testCommand = cmSystemTools::EscapeSpaces(this->FindExecutable(args[1].c_str()).c_str()); // continue if we did not find the executable if (testCommand == "") { std::cerr << "Unable to find executable: " << args[1].c_str() << "\n"; continue; } // add the arguments std::vector::iterator j = args.begin(); ++j; ++j; for(;j != args.end(); ++j) { testCommand += " "; testCommand += cmSystemTools::EscapeSpaces(j->c_str()); } /** * Run an executable command and put the stdout in output. */ std::string output; int retVal; if (!cmSystemTools::RunCommand(testCommand.c_str(), output, retVal, false) || retVal != 0) { fprintf(stderr,"***Failed\n"); if (output != "") { if (dartStuff.find(output.c_str())) { cmSystemTools::ReplaceString(output, dartStuff.match(1).c_str(),""); } if (output != "") { std::cerr << output.c_str() << "\n"; } } failed.push_back(args[0]); } else { fprintf(stderr," Passed\n"); if (output != "") { if (dartStuff.find(output.c_str())) { cmSystemTools::ReplaceString(output, dartStuff.match(1).c_str(),""); } if (output != "") { std::cerr << output.c_str() << "\n"; } } passed++; } } } } } // this is a test driver program for cmake. int main (int argc, char *argv[]) { int passed = 0; std::vector failed; int total; ctest inst; // look at the args std::vector args; for(int i =0; i < argc; ++i) { args.push_back(argv[i]); } for(unsigned int i=1; i < args.size(); ++i) { std::string arg = args[i]; if(arg.find("-D",0) == 0 && i < args.size() - 1) { inst.m_ConfigType = args[i+1]; } if(arg.find("-R",0) == 0 && i < args.size() - 1) { inst.m_UseIncludeRegExp = true; inst.m_IncludeRegExp = args[i+1]; } if(arg.find("-E",0) == 0 && i < args.size() - 1) { inst.m_UseExcludeRegExp = true; inst.m_ExcludeRegExp = args[i+1]; inst.m_UseExcludeRegExpFirst = inst.m_UseIncludeRegExp ? false : true; } } // call process directory inst.ProcessDirectory(passed, failed); total = passed + failed.size(); if (total == 0) { std::cerr << "No tests were found!!!\n"; } else { float percent = passed * 100.0 / total; fprintf(stderr,"%.0f%% tests passed, %i tests failed out of %i\n", percent, failed.size(), total); if (failed.size()) { std::cerr << "The following tests failed:\n"; for(std::vector::iterator j = failed.begin(); j != failed.end(); ++j) { std::cerr << "\t" << *j << "\n"; } } } return failed.size(); }