CTest: Fix test DEPEND cycle detection
A cycle exists when the DFS returns to the root node, not just when multiple paths lead to the same node. Inspired-By: Alexander Esilevich <aesilevich@pathscale.com>
This commit is contained in:
parent
a14a8562ea
commit
f48d3bc5ba
|
@ -653,32 +653,37 @@ bool cmCTestMultiProcessHandler::CheckCycles()
|
||||||
it != this->Tests.end(); ++it)
|
it != this->Tests.end(); ++it)
|
||||||
{
|
{
|
||||||
//DFS from each element to itself
|
//DFS from each element to itself
|
||||||
|
int root = it->first;
|
||||||
|
std::set<int> visited;
|
||||||
std::stack<int> s;
|
std::stack<int> s;
|
||||||
std::vector<int> visited;
|
s.push(root);
|
||||||
|
|
||||||
s.push(it->first);
|
|
||||||
|
|
||||||
while(!s.empty())
|
while(!s.empty())
|
||||||
{
|
{
|
||||||
int test = s.top();
|
int test = s.top();
|
||||||
s.pop();
|
s.pop();
|
||||||
|
if(visited.insert(test).second)
|
||||||
for(TestSet::iterator d = this->Tests[test].begin();
|
|
||||||
d != this->Tests[test].end(); ++d)
|
|
||||||
{
|
{
|
||||||
if(std::find(visited.begin(), visited.end(), *d) != visited.end())
|
for(TestSet::iterator d = this->Tests[test].begin();
|
||||||
|
d != this->Tests[test].end(); ++d)
|
||||||
{
|
{
|
||||||
//cycle exists
|
if(*d == root)
|
||||||
cmCTestLog(this->CTest, ERROR_MESSAGE, "Error: a cycle exists in "
|
{
|
||||||
"the test dependency graph for the test \""
|
//cycle exists
|
||||||
<< this->Properties[it->first]->Name << "\"." << std::endl
|
cmCTestLog(this->CTest, ERROR_MESSAGE, "Error: a cycle exists in "
|
||||||
<< "Please fix the cycle and run ctest again." << std::endl);
|
"the test dependency graph for the test \""
|
||||||
return false;
|
<< this->Properties[root]->Name << "\"." << std::endl
|
||||||
|
<< "Please fix the cycle and run ctest again." << std::endl);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
s.push(*d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s.push(*d);
|
|
||||||
}
|
}
|
||||||
visited.push_back(test);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||||
|
"Checking test dependency graph end" << std::endl);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -779,6 +779,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
||||||
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
||||||
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
|
--test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
|
||||||
)
|
)
|
||||||
|
SET_TESTS_PROPERTIES(testing PROPERTIES PASS_REGULAR_EXPRESSION "Passed")
|
||||||
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Testing")
|
LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Testing")
|
||||||
|
|
||||||
ADD_TEST(wrapping ${CMAKE_CTEST_COMMAND}
|
ADD_TEST(wrapping ${CMAKE_CTEST_COMMAND}
|
||||||
|
|
|
@ -3,3 +3,15 @@
|
||||||
#
|
#
|
||||||
ADD_EXECUTABLE(testing2 testing2.cxx)
|
ADD_EXECUTABLE(testing2 testing2.cxx)
|
||||||
ADD_TEST(testing.2 ${Testing_BINARY_DIR}/bin/testing2)
|
ADD_TEST(testing.2 ${Testing_BINARY_DIR}/bin/testing2)
|
||||||
|
|
||||||
|
add_test(NotCycle.a ${CMAKE_COMMAND} -E echo a)
|
||||||
|
add_test(NotCycle.test1 ${CMAKE_COMMAND} -E echo test1)
|
||||||
|
set_property(TEST NotCycle.test1 PROPERTY DEPENDS NotCycle.a)
|
||||||
|
|
||||||
|
add_test(NotCycle.b ${CMAKE_COMMAND} -E echo b)
|
||||||
|
add_test(NotCycle.test2 ${CMAKE_COMMAND} -E echo test2)
|
||||||
|
set_property(TEST NotCycle.test2 PROPERTY DEPENDS NotCycle.b NotCycle.test1)
|
||||||
|
|
||||||
|
add_test(NotCycle.c ${CMAKE_COMMAND} -E echo c)
|
||||||
|
add_test(NotCycle.test3 ${CMAKE_COMMAND} -E echo test3)
|
||||||
|
set_property(TEST NotCycle.test3 PROPERTY DEPENDS NotCycle.c NotCycle.test1 NotCycle.test2)
|
||||||
|
|
Loading…
Reference in New Issue