Merge topic 'parallel-memcheck'

6f9aaad CTest: create one output file per memcheck (#14303)
This commit is contained in:
Brad King 2013-08-08 13:55:19 -04:00 committed by CMake Topic Stage
commit d422ee362d
8 changed files with 103 additions and 56 deletions

View File

@ -89,7 +89,7 @@ void cmCTestBatchTestHandler::WriteTestCommand(int test, std::fstream& fout)
command = cmSystemTools::ConvertToOutputPath(command.c_str());
//Prepends memcheck args to our command string if this is a memcheck
this->TestHandler->GenerateTestCommand(processArgs);
this->TestHandler->GenerateTestCommand(processArgs, test);
processArgs.push_back(command);
for(std::vector<std::string>::iterator arg = processArgs.begin();

View File

@ -200,6 +200,7 @@ void cmCTestMemCheckHandler::Initialize()
this->CustomMaximumPassedTestOutputSize = 0;
this->CustomMaximumFailedTestOutputSize = 0;
this->MemoryTester = "";
this->MemoryTesterDynamicOptions.clear();
this->MemoryTesterOptions.clear();
this->MemoryTesterStyle = UNKNOWN;
this->MemoryTesterOutputFile = "";
@ -242,12 +243,28 @@ int cmCTestMemCheckHandler::PostProcessHandler()
//----------------------------------------------------------------------
void cmCTestMemCheckHandler::GenerateTestCommand(
std::vector<std::string>& args)
std::vector<std::string>& args, int test)
{
std::vector<cmStdString>::size_type pp;
std::string memcheckcommand = "";
memcheckcommand
cmStdString index;
cmOStringStream stream;
std::string memcheckcommand
= cmSystemTools::ConvertToOutputPath(this->MemoryTester.c_str());
stream << test;
index = stream.str();
for ( pp = 0; pp < this->MemoryTesterDynamicOptions.size(); pp ++ )
{
cmStdString arg = this->MemoryTesterDynamicOptions[pp];
cmStdString::size_type pos = arg.find("??");
if (pos != cmStdString::npos)
{
arg.replace(pos, 2, index);
}
args.push_back(arg);
memcheckcommand += " \"";
memcheckcommand += arg;
memcheckcommand += "\"";
}
for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ )
{
args.push_back(this->MemoryTesterOptions[pp]);
@ -478,7 +495,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
= cmSystemTools::ParseArguments(memoryTesterOptions.c_str());
this->MemoryTesterOutputFile
= this->CTest->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.log";
= this->CTest->GetBinaryDir()
+ "/Testing/Temporary/MemoryChecker.??.log";
switch ( this->MemoryTesterStyle )
{
@ -510,7 +528,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
}
std::string outputFile = "--log-file="
+ this->MemoryTesterOutputFile;
this->MemoryTesterOptions.push_back(outputFile);
this->MemoryTesterDynamicOptions.push_back(outputFile);
break;
}
case cmCTestMemCheckHandler::PURIFY:
@ -538,19 +556,19 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
outputFile = "-log-file=";
#endif
outputFile += this->MemoryTesterOutputFile;
this->MemoryTesterOptions.push_back(outputFile);
this->MemoryTesterDynamicOptions.push_back(outputFile);
break;
}
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
{
this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile;
std::string dpbdFile = this->CTest->GetBinaryDir()
+ "/Testing/Temporary/MemoryChecker.DPbd";
+ "/Testing/Temporary/MemoryChecker.??.DPbd";
this->BoundsCheckerDPBDFile = dpbdFile;
this->MemoryTesterOptions.push_back("/B");
this->MemoryTesterOptions.push_back(dpbdFile);
this->MemoryTesterOptions.push_back("/X");
this->MemoryTesterOptions.push_back(this->MemoryTesterOutputFile);
this->MemoryTesterDynamicOptions.push_back("/B");
this->MemoryTesterDynamicOptions.push_back(dpbdFile);
this->MemoryTesterDynamicOptions.push_back("/X");
this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
this->MemoryTesterOptions.push_back("/M");
break;
}
@ -898,25 +916,23 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
// This method puts the bounds checker output file into the output
// for the test
void
cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res)
cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
int test)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"PostProcessBoundsCheckerTest for : "
<< res.Name.c_str() << std::endl);
if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
cmStdString ofile = testOutputFileName(test);
if ( ofile.empty() )
{
std::string log = "Cannot find memory tester output file: "
+ this->MemoryTesterOutputFile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
return;
}
// put a scope around this to close ifs so the file can be removed
{
std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
std::ifstream ifs(ofile.c_str());
if ( !ifs )
{
std::string log = "Cannot read memory tester output file: "
+ this->MemoryTesterOutputFile;
std::string log = "Cannot read memory tester output file: " + ofile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
return;
}
@ -939,38 +955,39 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res)
}
void
cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res)
cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res,
int test)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"PostProcessPurifyTest for : "
<< res.Name.c_str() << std::endl);
appendMemTesterOutput(res);
appendMemTesterOutput(res, test);
}
void
cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res)
cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res,
int test)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
"PostProcessValgrindTest for : "
<< res.Name.c_str() << std::endl);
appendMemTesterOutput(res);
appendMemTesterOutput(res, test);
}
void
cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res)
cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
int test)
{
if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
cmStdString ofile = testOutputFileName(test);
if ( ofile.empty() )
{
std::string log = "Cannot find memory tester output file: "
+ this->MemoryTesterOutputFile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
return;
}
std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
std::ifstream ifs(ofile.c_str());
if ( !ifs )
{
std::string log = "Cannot read memory tester output file: "
+ this->MemoryTesterOutputFile;
std::string log = "Cannot read memory tester output file: " + ofile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
return;
}
@ -981,3 +998,25 @@ cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res)
res.Output += "\n";
}
}
cmStdString
cmCTestMemCheckHandler::testOutputFileName(int test)
{
cmStdString index;
cmOStringStream stream;
stream << test;
index = stream.str();
cmStdString ofile = this->MemoryTesterOutputFile;
cmStdString::size_type pos = ofile.find("??");
ofile.replace(pos, 2, index);
if ( !cmSystemTools::FileExists(ofile.c_str()) )
{
std::string log = "Cannot find memory tester output file: "
+ ofile;
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
ofile = "";
}
return ofile;
}

View File

@ -37,7 +37,7 @@ public:
protected:
virtual int PreProcessHandler();
virtual int PostProcessHandler();
virtual void GenerateTestCommand(std::vector<std::string>& args);
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
private:
@ -89,6 +89,7 @@ private:
std::string BoundsCheckerDPBDFile;
std::string BoundsCheckerXMLFile;
std::string MemoryTester;
std::vector<cmStdString> MemoryTesterDynamicOptions;
std::vector<cmStdString> MemoryTesterOptions;
int MemoryTesterStyle;
std::string MemoryTesterOutputFile;
@ -117,12 +118,16 @@ private:
bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
std::string& log, int* results);
void PostProcessPurifyTest(cmCTestTestResult& res);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res);
void PostProcessValgrindTest(cmCTestTestResult& res);
void PostProcessPurifyTest(cmCTestTestResult& res, int test);
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
void PostProcessValgrindTest(cmCTestTestResult& res, int test);
///! append MemoryTesterOutputFile to the test log
void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res);
void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
int test);
///! generate the output filename for the given test index
cmStdString testOutputFileName(int test);
};
#endif

View File

@ -389,13 +389,13 @@ void cmCTestRunTest::MemCheckPostProcess()
switch ( handler->MemoryTesterStyle )
{
case cmCTestMemCheckHandler::VALGRIND:
handler->PostProcessValgrindTest(this->TestResult);
handler->PostProcessValgrindTest(this->TestResult, this->Index);
break;
case cmCTestMemCheckHandler::PURIFY:
handler->PostProcessPurifyTest(this->TestResult);
handler->PostProcessPurifyTest(this->TestResult, this->Index);
break;
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
handler->PostProcessBoundsCheckerTest(this->TestResult);
handler->PostProcessBoundsCheckerTest(this->TestResult, this->Index);
break;
default:
break;
@ -524,7 +524,7 @@ void cmCTestRunTest::ComputeArguments()
= cmSystemTools::ConvertToOutputPath(this->ActualCommand.c_str());
//Prepends memcheck args to our command string
this->TestHandler->GenerateTestCommand(this->Arguments);
this->TestHandler->GenerateTestCommand(this->Arguments, this->Index);
for(std::vector<std::string>::iterator i = this->Arguments.begin();
i != this->Arguments.end(); ++i)
{

View File

@ -1107,7 +1107,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
}
//----------------------------------------------------------------------
void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&)
void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int)
{
}

View File

@ -153,7 +153,7 @@ protected:
// compute a final test list
virtual int PreProcessHandler();
virtual int PostProcessHandler();
virtual void GenerateTestCommand(std::vector<std::string>& args);
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
int ExecuteCommands(std::vector<cmStdString>& vec);
void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);

View File

@ -66,6 +66,7 @@ function(gen_mc_test NAME CHECKER)
-D PSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
-D PSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
-D ERROR_COMMAND=$<TARGET_FILE:memcheck_fail>
${ARGN}
)
endfunction(gen_mc_test)
@ -74,10 +75,11 @@ function(gen_mcnl_test NAME CHECKER)
-D PSEUDO_BC=$<TARGET_FILE:pseudonl_BC>
-D PSEUDO_PURIFY=$<TARGET_FILE:pseudonl_purify>
-D PSEUDO_VALGRIND=$<TARGET_FILE:pseudonl_valgrind>
${ARGN}
)
set_tests_properties(CTestTestMemcheck${NAME}
PROPERTIES
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
endfunction(gen_mcnl_test)
unset(CTEST_EXTRA_CONFIG)
@ -109,14 +111,17 @@ set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n")
set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
gen_mc_test(DummyValgrindIgnoreMemcheck "\${PSEUDO_VALGRIND}")
unset(CTEST_EXTRA_CONFIG)
gen_mc_test(DummyValgrindTwoTargets "\${PSEUDO_VALGRIND}" "-VV")
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")")
unset(CMAKELISTS_EXTRA_CODE)
gen_mc_test(DummyValgrindInvalidSupFile "\${PSEUDO_VALGRIND}")
# CTest will add the logfile option as last option. Tell the dummy memcheck
# to ignore that argument. This will cause the logfile to be missing, which
# will be the prove for us that the custom option is indeed used.
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--\")")
# CTest will add the logfile option before any custom options. Set the logfile
# again, this time to an empty string. This will cause the logfile to be
# missing, which will be the prove for us that the custom option is indeed used.
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")")
gen_mc_test(DummyValgrindCustomOptions "\${PSEUDO_VALGRIND}")
unset(CTEST_EXTRA_CONFIG)
@ -161,4 +166,8 @@ set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES
PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n")
set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES
PASS_REGULAR_EXPRESSION
"\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n")

View File

@ -28,12 +28,6 @@ main(int argc, char **argv)
std::string logfile;
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
// stop processing options, this allows to force
// the logfile to be ignored
if (arg == "--")
{
break;
}
if (arg.find(logarg) == 0)
{
if (nextarg)
@ -46,7 +40,7 @@ main(int argc, char **argv)
{
logfile = arg.substr(logarg.length());
}
break;
// keep searching, it may be overridden later to provoke an error
}
}