Added ctest -N test. Fixed ctest working directory bug. MemCheck fix coming soon...

This commit is contained in:
Zach Mullen 2009-08-28 11:08:39 -04:00
parent 00ca781088
commit b427d1985e
8 changed files with 117 additions and 153 deletions

View File

@ -867,7 +867,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
} }
return true; return true;
} }
//TODO ZACH move this logic into cmCTestRunTest
void void
cmCTestMemCheckHandler::ProcessOneTest(cmCTestTestProperties *props, cmCTestMemCheckHandler::ProcessOneTest(cmCTestTestProperties *props,
std::vector<cmStdString> &passed, std::vector<cmStdString> &passed,

View File

@ -24,6 +24,7 @@
cmCTestMultiProcessHandler::cmCTestMultiProcessHandler() cmCTestMultiProcessHandler::cmCTestMultiProcessHandler()
{ {
this->ParallelLevel = 1; this->ParallelLevel = 1;
this->Completed = 0;
} }
// Set the tests // Set the tests
void void
@ -38,6 +39,7 @@ cmCTestMultiProcessHandler::SetTests(TestMap& tests,
this->TestFinishMap[i->first] = false; this->TestFinishMap[i->first] = false;
} }
this->Tests = tests; this->Tests = tests;
this->Total = this->Tests.size();
this->Properties = properties; this->Properties = properties;
} }
@ -81,7 +83,7 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
} }
else else
{ {
testRun->EndTest(); testRun->EndTest(this->Completed, this->Total);
} }
} }
@ -130,9 +132,9 @@ bool cmCTestMultiProcessHandler::StartTest(int test)
void cmCTestMultiProcessHandler::StartNextTests() void cmCTestMultiProcessHandler::StartNextTests()
{ {
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl //cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
<< "Number of running tests : " << this->RunningTests.size() // << "Number of running tests : " << this->RunningTests.size()
<< "\n"); // << "\n");
size_t numToStart = this->ParallelLevel - this->RunningTests.size(); size_t numToStart = this->ParallelLevel - this->RunningTests.size();
if(numToStart == 0) if(numToStart == 0)
{ {
@ -183,16 +185,17 @@ bool cmCTestMultiProcessHandler::CheckOutput()
for( std::vector<cmCTestRunTest*>::iterator i = finished.begin(); for( std::vector<cmCTestRunTest*>::iterator i = finished.begin();
i != finished.end(); ++i) i != finished.end(); ++i)
{ {
this->Completed++;
cmCTestRunTest* p = *i; cmCTestRunTest* p = *i;
int test = p->GetIndex(); int test = p->GetIndex();
if(p->EndTest()) if(p->EndTest(this->Completed, this->Total))
{ {
this->Passed->push_back(p->GetTestProperties()->Name); this->Passed->push_back(p->GetTestProperties()->Name);
} }
else else
{ {
this->Failed->push_back(p->GetTestProperties()->Name); this->Failed->push_back(p->GetTestProperties()->Name);
} }
for(TestMap::iterator j = this->Tests.begin(); for(TestMap::iterator j = this->Tests.begin();
j!= this->Tests.end(); ++j) j!= this->Tests.end(); ++j)
@ -226,19 +229,38 @@ void cmCTestMultiProcessHandler::MarkFinished()
cmSystemTools::RemoveFile(fname.c_str()); cmSystemTools::RemoveFile(fname.c_str());
} }
void cmCTestMultiProcessHandler::PrintTests() //---------------------------------------------------------------------
//For ShowOnly mode
void cmCTestMultiProcessHandler::PrintTestList()
{ {
#undef cout int count = 0;
for( TestMap::iterator i = this->Tests.begin(); for (PropertiesMap::iterator it = this->Properties.begin();
i!= this->Tests.end(); ++i) it != this->Properties.end(); it ++ )
{ {
std::cout << "Test " << i->first << " ("; count++;
for(TestSet::iterator j = i->second.begin(); cmCTestTestHandler::cmCTestTestProperties& p = *it->second;
j != i->second.end(); ++j)
cmCTestRunTest testRun;
testRun.SetCTest(this->CTest);
testRun.SetTestHandler(this->TestHandler);
testRun.SetIndex(p.Index);
testRun.SetTestProperties(&p);
testRun.ComputeArguments(); //logs the command in verbose mode
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< count << "/");
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< this->Total << " ");
if (this->TestHandler->MemCheck)
{ {
std::cout << *j << " "; cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory Check");
} }
std::cout << ")\n"; else
{
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Testing");
}
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
cmCTestLog(this->CTest, HANDLER_OUTPUT, p.Name.c_str() << std::endl);
} }
} }
@ -282,42 +304,5 @@ void cmCTestMultiProcessHandler::RemoveTest(int index)
this->Properties.erase(index); this->Properties.erase(index);
this->TestRunningMap[index] = false; this->TestRunningMap[index] = false;
this->TestFinishMap[index] = true; this->TestFinishMap[index] = true;
this->Completed++;
} }
#if 0
int main()
{
cmCTestMultiProcessHandler h;
h.SetParallelLevel(4);
std::map<int, std::set<int> > tests;
std::set<int> depends;
for(int i =1; i < 92; i++)
{
tests[i] = depends;
}
depends.clear();
depends.insert(45); subprject
tests[46] = depends; subproject-stage2
depends.clear();
depends.insert(55); simpleinstall simpleinstall-s2
tests[56] = depends;
depends.clear();
depends.insert(70); wrapping
tests[71] = depends; qtwrapping
depends.clear();
depends.insert(71); qtwrapping
tests[72] = depends; testdriver1
depends.clear();
depends.insert(72) testdriver1
tests[73] = depends; testdriver2
depends.clear();
depends.insert(73); testdriver2
tests[74] = depends; testdriver3
depends.clear();
depends.insert(79); linkorder1
tests[80] = depends; linkorder2
h.SetTests(tests);
h.PrintTests();
h.RunTests();
}
#endif

View File

@ -40,7 +40,7 @@ public:
// Set the max number of tests that can be run at the same time. // Set the max number of tests that can be run at the same time.
void SetParallelLevel(size_t); void SetParallelLevel(size_t);
void RunTests(); void RunTests();
void PrintTests(); void PrintTestList();
//void SetCTestCommand(const char* c) { this->CTestCommand = c;} //void SetCTestCommand(const char* c) { this->CTestCommand = c;}
//void SetTestCacheFile(const char* c) { this->CTestCacheFile = c;} //void SetTestCacheFile(const char* c) { this->CTestCacheFile = c;}
void SetPassFailVectors(std::vector<cmStdString>* passed, void SetPassFailVectors(std::vector<cmStdString>* passed,
@ -80,6 +80,10 @@ protected:
void CheckResume(); void CheckResume();
// map from test number to set of depend tests // map from test number to set of depend tests
TestMap Tests; TestMap Tests;
//Total number of tests we'll be running
int Total;
//Number of tests that are complete
int Completed;
//list of test properties (indices concurrent to the test map) //list of test properties (indices concurrent to the test map)
PropertiesMap Properties; PropertiesMap Properties;
std::map<int, bool> TestRunningMap; std::map<int, bool> TestRunningMap;

View File

@ -55,14 +55,14 @@ void cmCTestRunTest::CheckOutput()
} }
//--------------------------------------------------------- //---------------------------------------------------------
bool cmCTestRunTest::EndTest() bool cmCTestRunTest::EndTest(int completed, int total)
{ {
//restore the old environment //restore the old environment
if (this->ModifyEnv) if (this->ModifyEnv)
{ {
cmSystemTools::RestoreEnv(this->OrigEnv); cmSystemTools::RestoreEnv(this->OrigEnv);
} }
this->WriteLogOutputTop(); this->WriteLogOutputTop(completed, total);
std::string reason; std::string reason;
bool passed = true; bool passed = true;
int res = this->TestProcess->GetProcessStatus(); int res = this->TestProcess->GetProcessStatus();
@ -259,6 +259,7 @@ void cmCTestRunTest::SetTestHandler(cmCTestTestHandler * handler)
// Starts the execution of a test. Returns once it has started // Starts the execution of a test. Returns once it has started
bool cmCTestRunTest::StartTest() bool cmCTestRunTest::StartTest()
{ {
this->ComputeArguments();
std::vector<std::string>& args = this->TestProperties->Args; std::vector<std::string>& args = this->TestProperties->Args;
this->TestResult.Properties = this->TestProperties; this->TestResult.Properties = this->TestProperties;
this->TestResult.ExecutionTime = 0; this->TestResult.ExecutionTime = 0;
@ -268,12 +269,6 @@ bool cmCTestRunTest::StartTest()
this->TestResult.Name = this->TestProperties->Name; this->TestResult.Name = this->TestProperties->Name;
this->TestResult.Path = this->TestProperties->Directory.c_str(); this->TestResult.Path = this->TestProperties->Directory.c_str();
// find the test executable
this->ActualCommand
= this->TestHandler->FindTheExecutable(args[1].c_str());
this->TestCommand
= cmSystemTools::ConvertToOutputPath(this->ActualCommand.c_str());
// continue if we did not find the executable // continue if we did not find the executable
if (this->TestCommand == "") if (this->TestCommand == "")
{ {
@ -289,22 +284,42 @@ bool cmCTestRunTest::StartTest()
return false; return false;
} }
} }
this->StartTime = this->CTest->CurrentTime();
return this->CreateProcess(this->TestProperties->Timeout,
&this->TestProperties->Environment);
}
void cmCTestRunTest::ComputeArguments()
{
std::vector<std::string>& args = this->TestProperties->Args;
// find the test executable
this->ActualCommand
= this->TestHandler->FindTheExecutable(args[1].c_str());
this->TestCommand
= cmSystemTools::ConvertToOutputPath(this->ActualCommand.c_str());
// add the arguments
std::vector<std::string>::const_iterator j =
this->TestProperties->Args.begin();
++j; // skip test name
++j; // skip command as it is in actualCommand
//TODO ZACH the problem is here for memcheck. We need to call
//memcheckhandler.GenerateTestCommand BEFORE we run the process.
// this->TestHandler->GenerateTestCommand(this->Arguments);
for(;j != this->TestProperties->Args.end(); ++j)
{
this->TestCommand += " ";
this->TestCommand += cmSystemTools::EscapeSpaces(j->c_str());
this->Arguments.push_back(*j);
}
this->TestResult.FullCommandLine = this->TestCommand;
/**
* Run an executable command and put the stdout in output.
*/
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl
<< this->Index << ": " << this->Index << ": "
<< (this->TestHandler->MemCheck?"MemCheck":"Test") << (this->TestHandler->MemCheck?"MemCheck":"Test")
<< " command: " << this->TestCommand << " command: " << this->TestCommand
<< std::endl); << std::endl);
this->StartTime = this->CTest->CurrentTime();
return this->CreateProcess(this->ActualCommand,
this->TestProperties->Args,
this->TestProperties->Timeout,
&this->TestProperties->Environment);
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
@ -330,24 +345,14 @@ void cmCTestRunTest::DartProcessing()
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------
bool cmCTestRunTest::CreateProcess(std::string command, bool cmCTestRunTest::CreateProcess(double testTimeOut,
std::vector<std::string> args,
double testTimeOut,
std::vector<std::string>* environment) std::vector<std::string>* environment)
{ {
std::vector<std::string> commandArgs;
std::vector<std::string>::iterator i = args.begin();
++i; //skip test name
++i; //skip executable name
for(; i != args.end(); ++i)
{
commandArgs.push_back(*i);
}
this->TestProcess = new cmProcess; this->TestProcess = new cmProcess;
this->TestProcess->SetId(this->Index); this->TestProcess->SetId(this->Index);
this->TestProcess->SetCommand(command.c_str()); this->TestProcess->SetWorkingDirectory(this->TestProperties->Directory.c_str());
this->TestProcess->SetCommandArguments(commandArgs); this->TestProcess->SetCommand(this->ActualCommand.c_str());
this->TestProcess->SetCommandArguments(this->Arguments);
std::vector<std::string> origEnv; std::vector<std::string> origEnv;
this->ModifyEnv = (environment && environment->size()>0); this->ModifyEnv = (environment && environment->size()>0);
@ -380,15 +385,16 @@ bool cmCTestRunTest::CreateProcess(std::string command,
return this->TestProcess->StartProcess(); return this->TestProcess->StartProcess();
} }
void cmCTestRunTest::WriteLogOutputTop() void cmCTestRunTest::WriteLogOutputTop(int completed, int total)
{ {
/* Not sure whether we want to prepend the test index anymore /* Not sure whether we want to prepend the test index anymore
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3) cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< this->Index << ": ");*/ << this->Index << ": ");*/
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3) cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< this->TestProperties->Index << "/"); << completed << "/");
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3) cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< this->TestHandler->TotalNumberOfTests << " "); << total << " ");
if ( this->TestHandler->MemCheck ) if ( this->TestHandler->MemCheck )
{ {
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory Check"); cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory Check");
@ -397,39 +403,29 @@ void cmCTestRunTest::WriteLogOutputTop()
{ {
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Testing"); cmCTestLog(this->CTest, HANDLER_OUTPUT, "Testing");
} }
std::stringstream indexStr;
indexStr << " (" << this->Index << ")";
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(6)
<< indexStr.str().c_str());
cmCTestLog(this->CTest, HANDLER_OUTPUT, " "); cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth(); const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
std::string outname = this->TestProperties->Name + " "; std::string outname = this->TestProperties->Name + " ";
outname.resize(maxTestNameWidth, '.'); outname.resize(maxTestNameWidth, '.');
// add the arguments
std::vector<std::string>::const_iterator j =
this->TestProperties->Args.begin();
++j; // skip test name
++j; // skip command as it is in actualCommand
std::vector<const char*> arguments;
this->TestHandler->GenerateTestCommand(arguments);
arguments.push_back(this->ActualCommand.c_str());
for(;j != this->TestProperties->Args.end(); ++j)
{
this->TestCommand += " ";
this->TestCommand += cmSystemTools::EscapeSpaces(j->c_str());
arguments.push_back(j->c_str());
}
arguments.push_back(0);
this->TestResult.FullCommandLine = this->TestCommand;
*this->TestHandler->LogFile << this->TestProperties->Index << "/" *this->TestHandler->LogFile << this->TestProperties->Index << "/"
<< this->TestHandler->TotalNumberOfTests << " Testing: " << this->TestHandler->TotalNumberOfTests << " Testing: "
<< this->TestProperties->Name << std::endl; << this->TestProperties->Name << std::endl;
*this->TestHandler->LogFile << this->TestProperties->Index << "/" *this->TestHandler->LogFile << this->TestProperties->Index << "/"
<< this->TestHandler->TotalNumberOfTests << this->TestHandler->TotalNumberOfTests
<< " Test: " << this->TestProperties->Name.c_str() << std::endl; << " Test: " << this->TestProperties->Name.c_str() << std::endl;
*this->TestHandler->LogFile << "Command: "; *this->TestHandler->LogFile << "Command: \"" << this->ActualCommand << "\"";
std::vector<cmStdString>::size_type ll;
for ( ll = 0; ll < arguments.size()-1; ll ++ ) for (std::vector<std::string>::iterator i = this->Arguments.begin();
i != this->Arguments.end(); ++i)
{ {
*this->TestHandler->LogFile << "\"" << arguments[ll] << "\" "; *this->TestHandler->LogFile
<< " \"" << i->c_str() << "\"";
} }
*this->TestHandler->LogFile << std::endl *this->TestHandler->LogFile << std::endl
<< "Directory: " << this->TestProperties->Directory << std::endl << "Directory: " << this->TestProperties->Directory << std::endl

View File

@ -55,15 +55,15 @@ public:
void CheckOutput(); void CheckOutput();
//launch the test process, return whether it started correctly //launch the test process, return whether it started correctly
bool StartTest(); bool StartTest();
//capture the test results and send them back to the test handler //capture and report the test results
bool EndTest(); bool EndTest(int completed, int total);
protected: //Called by ctest -N to log the command string
void ComputeArguments();
private:
void DartProcessing(); void DartProcessing();
bool CreateProcess(std::string executable, bool CreateProcess(double testTimeOut,
std::vector<std::string> args,
double testTimeOut,
std::vector<std::string>* environment); std::vector<std::string>* environment);
void WriteLogOutputTop(); void WriteLogOutputTop(int completed, int total);
cmCTestTestHandler::cmCTestTestProperties * TestProperties; cmCTestTestHandler::cmCTestTestProperties * TestProperties;
//Pointer back to the "parent"; the handler that invoked this test run //Pointer back to the "parent"; the handler that invoked this test run
@ -86,6 +86,7 @@ protected:
std::string StartTime; std::string StartTime;
std::string TestCommand; std::string TestCommand;
std::string ActualCommand; std::string ActualCommand;
std::vector<std::string> Arguments;
}; };
#endif #endif

View File

@ -1303,42 +1303,12 @@ bool cmCTestTestHandler::GetValue(const char* tag,
return ret; return ret;
} }
//---------------------------------------------------------------------
void cmCTestTestHandler::PrintTestList()
{
int total = this->TotalNumberOfTests;
for (ListOfTests::iterator it = this->TestList.begin();
it != this->TestList.end(); it ++ )
{
cmCTestTestProperties& p = *it;
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< p.Index << "/");
cmCTestLog(this->CTest, HANDLER_OUTPUT, std::setw(3)
<< total << " ");
if (this->MemCheck)
{
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Memory Check");
}
else
{
cmCTestLog(this->CTest, HANDLER_OUTPUT, "Testing");
}
cmCTestLog(this->CTest, HANDLER_OUTPUT, " ");
cmCTestLog(this->CTest, HANDLER_OUTPUT, p.Name.c_str() << std::endl);
}
}
//--------------------------------------------------------------------- //---------------------------------------------------------------------
void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed, void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
std::vector<cmStdString> &failed) std::vector<cmStdString> &failed)
{ {
this->ComputeTestList(); this->ComputeTestList();
if(this->CTest->GetShowOnly())
{
this->PrintTestList();
return;
}
cmCTestMultiProcessHandler parallel; cmCTestMultiProcessHandler parallel;
parallel.SetCTest(this->CTest); parallel.SetCTest(this->CTest);
parallel.SetParallelLevel(this->CTest->GetParallelLevel()); parallel.SetParallelLevel(this->CTest->GetParallelLevel());
@ -1380,8 +1350,14 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
parallel.SetPassFailVectors(&passed, &failed); parallel.SetPassFailVectors(&passed, &failed);
this->TestResults.clear(); this->TestResults.clear();
parallel.SetTestResults(&this->TestResults); parallel.SetTestResults(&this->TestResults);
parallel.RunTests(); if(this->CTest->GetShowOnly())
{
parallel.PrintTestList();
}
else
{
parallel.RunTests();
}
*this->LogFile << "End testing: " *this->LogFile << "End testing: "
<< this->CTest->CurrentTime() << std::endl; << this->CTest->CurrentTime() << std::endl;
} }

View File

@ -141,7 +141,6 @@ protected:
void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result); void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);
void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result); void WriteTestResultFooter(std::ostream& os, cmCTestTestResult* result);
void PrintTestList();
//! Clean test output to specified length //! Clean test output to specified length
bool CleanTestOutput(std::string& output, size_t length); bool CleanTestOutput(std::string& output, size_t length);

View File

@ -1052,6 +1052,9 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=CVS -P ${CMake_SOURCE_DIR}/Utilities/Rel
-S "${CMake_BINARY_DIR}/Tests/CTestTest3/test.cmake" -V -S "${CMake_BINARY_DIR}/Tests/CTestTest3/test.cmake" -V
--output-log "${CMake_BINARY_DIR}/Tests/CTestTest3/testOutput.log" --output-log "${CMake_BINARY_DIR}/Tests/CTestTest3/testOutput.log"
) )
ADD_TEST(CTestTestShowOnly ${CMAKE_CTEST_COMMAND}
-N
)
# these tests take a long time, make sure they have it # these tests take a long time, make sure they have it
# if timeouts have not already been set # if timeouts have not already been set
GET_TEST_PROPERTY(CTestTest TIMEOUT PREVIOUS_TIMEOUT) GET_TEST_PROPERTY(CTestTest TIMEOUT PREVIOUS_TIMEOUT)